当前位置:  建站>运营/SEO
本页文章导读:
    ▪svnsync 同步      Step 1. svnadmin create Run once @echo off echo --------------------------------------------------------------------------- echo %date:~0,10% %time% echo Start... echo Creating myrep... svnadmin create myrep echo End. echo ---------------------------.........
    ▪《谈谈windows核心编程系列》 结构化异常处理SEH之__finally终止处理              结构化异常处理SEH:__finally终止处理。   结构化异常处理(Structuredexception handling)简称SEH。是windows系统提供的异常处理机制。促使windows将SEH加入到windows系.........
    ▪linux网络协议栈分析笔记10-arp邻居子系统3       还是回到neigh_resolve_output() int neigh_resolve_output(struct sk_buff *skb) {      struct dst_entry *dst = skb_dst(skb);      struct neighbour *neigh;      int rc = 0;   .........

[1]svnsync 同步
    来源: 互联网  发布时间: 2013-10-27

Step 1. svnadmin create

Run once

@echo off
echo ---------------------------------------------------------------------------
echo %date:~0,10% %time%
echo Start...
echo Creating myrep...
svnadmin create myrep
echo End.
echo ---------------------------------------------------------------------------


Step 2. svnsync init

Run once


@echo off
echo ---------------------------------------------------------------------------
echo %date:~0,10% %time%
echo Start...
echo Initing myrepo...
svnsync init file:///E:/Repositories/myrepo http://ip/svn/myrepo --usernmae me --password *

echo End.
echo ---------------------------------------------------------------------------


Step 3. svnsync sync

Run whenver you want

@echo off
echo ---------------------------------------------------------------------------
echo %date:~0,10% %time%
echo Start...
echo Syncing myrepo...
svnsync sync file:///E:/Repositories/myrepo

echo End.
echo ---------------------------------------------------------------------------



作者:abing0214 发表于2013-4-12 10:57:06 原文链接
阅读:62 评论:0 查看评论

    
[2]《谈谈windows核心编程系列》 结构化异常处理SEH之__finally终止处理
    来源: 互联网  发布时间: 2013-10-27

        结构化异常处理SEH:__finally终止处理。

 

  结构化异常处理(Structuredexception handling)简称SEH。是windows系统提供的异常处理机制。促使windows将SEH加入到windows系统的一个关键原因就是:它可以简化操作系统本身的开发工作,同时还让系统更加健壮。

我们当然也可以在我们的程序中添加SEH机制,这样我们的应用程序也可以变得更加健壮。使用SEH,我们在编写代码时可以先集中精力完成软件的正常工作流程。也就是说将软件主要功能编写和软件异常处理这两个任务分离开,最后再去处理软件可能遇到的各种错误情况。

为了实现SEH,编译器完成了很多的工作。在进入和离开异常处理代码时编译器会插入一些额外的代码,有时这会导致很大的开销。后面的文章我会介绍编译器都是做了哪些工作。

虽然不同的厂商按照不同的方式来实现SEH,但是大部分的编译厂商都遵循了microsoft的语法规则。因此本文我们将介绍Microsoft visualC++编译器规定的语法。

SEH包括两个方面的内容:终止处理和异常处理。本文我们介绍终止处理,下一篇文章将介绍异常处理。

 

终止处理

终止处理程序确保无论一个代码块是如何退出的,都能保证该终止处理程序能够被执行。其语法如下:

__try
{
   //被保护的代码。
}
__finally//终止处理。
{
   //终止处理代码。
}


注意:try和finally前都有两个下划线。

终止程序也分为两个部分:__try块为中止处理程序要保护的代码。无论程序以何种方式从该块中退出(如return、goto等语句),__finally块都会被执行。

__finally块为终止处理程序块,该块中的代码会在控制流从__try块退出后、程序结束之前被调用。一般用来执行一些清理操作,如释放资源、释放占有的互斥量等。

但是上面所说的”无论何种方式“有些绝对。因为这个世界本来就没有绝对的东西。当在try块中使用了ExitProcess、ExitThread、TerminateProcess、TerminateThread来终止线程或进程时,finally块就不会被调用。要特别注意这些例外,禁止在try块中使用这些函数。

下面通过代码给大家讲解终止处理程序的使用:

__try
{
    WaitForSingleObject(hMutex,INFINITE);
    if(x==false)
       return-1;
}
__finally
{
          ReleaseMutex(hMutex);
      return -2;
}
return 0;


可以看到上面的代码在try中首先等待互斥量内核对象被触发,等待成功后互斥量就属于该线程所有。如果此时执行return-1,则该线程结束,就会导致互斥量对象一直被占有的情况的发生,其他线程会一直处于等待状态。这就是所谓的资源泄漏。有了finally块的保护后,当执行return-1程序试图退出try块时,编译器会让finally块在return之前执行,同时在return(其他语句,如goto等语句也一样)语句之前插入一些代码。return的返回值会被保存在一个临时变量中。

但上面的代码程序的返回值是多少呢?是-1,还是-2呢?答案是-2。当编译器在try块中检测到return语句时,虽然会生成一些代码将返回值保存在一个临时变量中。但是由于finally块代码中也有一个return,finally块中return的值会将原来的返回值覆盖。所以函数最终返回-2。

这个过程被称为局部展开。局部展开会在系统因为try块中的代码提前退出时发生。局部展开会导致非常大的额外开销,因为编译器必须插入代码来保证finally块在程序退出之前执行。最理想的情况就是代码控制流正常的离开try块而进入到finally块中,这时的额外开销最小。在x86体系下离开try块正常进入到finally块只需要执行一条指令。

因此为了将性能开销降到最低,我们改进了上面的代码:

__try
{
      WaitForSingleObject(hMutex,INFINITE);
    if(x==false)
     gotoEndOfTryBlock;
   //一些代码。
  EndOfTryBlock:
}
__finally
{
   ReleaseMutex(hMutex);
    return -2;
}
return 0;


在上面改进后的代码中,当在try块中检查到错误发生时不再直接调用return强制退出。而是执行了一条goto语句到try块的末尾。执行此跳转后,控制流从try块中正常退出,直接进入到finally块中。由于没有发生局部展开,编译器不需要插入额外指令,也就没有导致额外的开销。

 

由于goto语句会破坏程序的执行流程,很多书上都再三强调禁止使用goto。其实我们也没有必要使用goto,因为microsoft提供给我们一个关键字_leave,也可以执行类似的操作。关键字_leave会导致代码执行控制流跳转到try块的末尾,从而代码将正常的从try块进入到finally块中。

下面为使用__leave关键字的改进代码:

__try
{
      WaitForSingleObject(hMutex,INFINITE);
    if(x==false)
    __leave
   //一些代码。
}
__finally
{
   ReleaseMutex(hMutex);
    return -2;
}
return 0;
 


本章开头曾介绍过使用SEH可以让程序员将程序正常执行流程和错误处理分开。下面我们分别展示两个例子,一个没有使用SEH,而另一个使用SEH,看下它们到底有何差别,通过比较我们也可以更好的知道SEH是如何完成上述工作的。

下面是没有使用SEH的程序:

bool fun(char* fileName)
{
      HANDLEhFile=CreateFile(....);
      if(hFile==INVALID_HANDLE_VALUE)
      {
           returnfalse;
      }
      HANDLEhFileMapping=CreateFileMapping(...);
      if(hFile==NULL)
      {
           CloseHandle(hFile);
           returnfalse;
 
      }
      char*p=MapViewOfFile(..);
      if(p==NULL)
      {
           CloseHandle(hFile);
           CloseHandle(hFileMapping);
            return false;
      }
 
      //其他工作.......
      returntrue;
}


 

相信我们很多人都写过类似上面的代码。我们可以看到,上面的代码中包含了很多错误检查和资源清理的代码。过多的错误代码检查和资源清理工作会使得代码难以阅读,同时也难以编写、修改和维护。

现在让我们来通过使用SEH机制改进上面的代码:

bool fun(char* fileName)
{
      HANDLEhFile=INVALID_HANDLE_VALUE;
      HANDLEhFileMapping=NULL;
      char*p=NULL;
      __try
      {
           hFile=CreateFile(....);
           if(hFile==INVALID_HANDLE_VALUE)
                 __leave;
            hFileMapping=CreateFileMapping(...);
           if(hFile==NULL)
                 __leave;        
           p=MapViewOfFile(..);
           if(p==NULL)
                 __leave;
      //其他代码。
      }
      __finally
      {
           if(hFile!=INVALID_HANDLE_VALUE)
                 CloseHandle(hFile);
           if(hFileMapping)
                 CloseHandle(hFileMapping);
 
      }
      returntrue;
}


从上面的代码我们可以看到代码简洁多了。清理工作放在最后执行,且能够保证能得到执行,代码看起来简洁而有序,

    
[3]linux网络协议栈分析笔记10-arp邻居子系统3
    来源: 互联网  发布时间: 2013-10-27
还是回到neigh_resolve_output()
int neigh_resolve_output(struct sk_buff *skb)
{
     struct dst_entry *dst = skb_dst(skb);
     struct neighbour *neigh;
     int rc = 0;

     if (!dst || !(neigh = dst->neighbour))        异常退出
          goto discard;

     __skb_pull(skb, skb_network_offset(skb));

     if (!neigh_event_send(neigh, skb)) {           判断邻居项是否有可用状态,如果可用,则把数据包发送出去
           int err;
          struct net_device *dev = neigh->dev;
          if (dev->header_ops->cache && !dst->hh) {
               write_lock_bh(&neigh->lock);
               if (!dst->hh)
                    neigh_hh_init(neigh, dst, dst->ops->protocol);
               err = dev_hard_header(skb, dev, ntohs(skb->protocol),
                               neigh->ha, NULL, skb->len);
               write_unlock_bh(&neigh->lock);
          } else {
               read_lock_bh(&neigh->lock);
               err = dev_hard_header(skb, dev, ntohs(skb->protocol),
                               neigh->ha, NULL, skb->len);
               read_unlock_bh(&neigh->lock);
          }
          if (err >= 0)
               rc = neigh->ops->queue_xmit(skb);
          else
               goto out_kfree_skb;
     }
out:
     return rc;
discard:
     NEIGH_PRINTK1("neigh_resolve_output: dst=%p neigh=%p\n",
                dst, dst ? dst->neighbour : NULL);
out_kfree_skb:
     rc = -EINVAL;
     kfree_skb(skb);
     goto out;
}
我们看邻居项可用的情况下的发送过程:
struct net_device *dev = neigh->dev;
          if (dev->header_ops->cache && !dst->hh) {      如果hh为空   邻居项的高速缓存
               write_lock_bh(&neigh->lock);
               if (!dst->hh)
                    neigh_hh_init(neigh, dst, dst->ops->protocol);                进行hh的初始化
               err = dev_hard_header(skb, dev, ntohs(skb->protocol),
                               neigh->ha, NULL, skb->len);             根据HH的信息构造二层头
               write_unlock_bh(&neigh->lock);
          } else {                                                      hh不为空时,直接根据HH的信息构造二层头
               read_lock_bh(&neigh->lock);
               err = dev_hard_header(skb, dev, ntohs(skb->protocol),
                               neigh->ha, NULL, skb->len);
               read_unlock_bh(&neigh->lock);
          }
          if (err >= 0)                                            加头成功直接输出
               rc = neigh->ops->queue_xmit(skb);         
          else
               goto out_kfree_skb;

static const struct neigh_ops arp_hh_ops = {
     .family =          AF_INET,
     .solicit =          arp_solicit,
     .error_report =          arp_error_report,
     .output =          neigh_resolve_output,
     .connected_output =     neigh_resolve_output,
     .hh_output =          dev_queue_xmit,
     .queue_xmit =          dev_queue_xmit,
};
static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst,
                 __be16 protocol)
{
     struct hh_cache     *hh;
     struct net_device *dev = dst->dev;

     for (hh = n->hh; hh; hh = hh->hh_next)             从路由的协议下手找
          if (hh->hh_type == protocol)
               break;

     if (!hh && (hh = kzalloc(sizeof(*hh), GFP_ATOMIC)) != NULL) {  找不到则申请
          seqlock_init(&hh->hh_lock);
          hh->hh_type = protocol;                     协议类型赋值
          atomic_set(&hh->hh_refcnt, 0);
          hh->hh_next = NULL;

          if (dev->header_ops->cache(n, hh)) {             该函数为eth_header_cache
               kfree(hh);
               hh = NUL
    
最新技术文章:
▪SQVI和SAP查询QUERY的区别和使用注意事项    ▪彻底理解Cisco/Linux/Windows的IP路由    ▪Exchange 2010 处于禁止发送用户自动收到来自IT...
▪MB_CHANGE_DOCUMENT使用方法    ▪ALV的html表头    ▪【译】如何精确判断最终用户响应时间过长的...
▪apache2.4.4启用deflate压缩    ▪使用vmware 配置centos 6.0+ 网络出现的各种问题...    ▪十句话教你学会Linux数据流重定向
▪centos6.x已经安装的系统添加图形界面    ▪Linux查看CPU和内存使用情况    ▪win7问题解决,凭据管理器和无法访问,不允...
▪Dynamics CRM 2013 初体验(4):不再被支持的功...    ▪win7下制作ubuntu系统安装启动盘和U盘安装ubuntu...    ▪Linux cp -a用法
▪Windows Server时间服务器配置方法    ▪Tomcat+memcached实现Session共享    ▪Linux修改系统环境变量PATH路径的方法
▪Citrix 服务器虚拟化之二十七 XenApp6.5发布服务...    ▪搭建本地Ubuntu 镜像服务器    ▪Create local metadata resource of yum
▪tsm ANS0326E问题处理    ▪Windows SVN变化邮件通知(Python2.7实现)    ▪linux下的内核测试工具——perf使用简介
▪Nginx TCP Proxy模块的编译安装    ▪OSX: SSH密钥使用日记(2)    ▪OSX: SSH密钥使用日记(1)
▪Manually start and stop Oracle XE in Ubuntu    ▪Disable autostart of Oracle-xe in Ubuntu    ▪tar命令-linux
▪xtrabackup-2.1.2-611安装    ▪无废话ubuntu 13.4文件共享配置    ▪Unix文本处理工具之sed
▪hpux 操作系统 磁带备份与恢复    ▪HP DL360 G7通过iLO部署系统    ▪Redhat 6.0中VNC Server的配置方法
▪hpux 操作系统磁带备份与恢复    ▪用C++编程调用libvirt的API来创建KVM虚拟机    ▪hpux- hp小型机日常硬件故障处理case(一)
▪web集群时session同步的几种方法(统计)    ▪inux常用命令大全    ▪BAT 批处理实现循环备份N天文件夹
▪BIND9私有DNS服务器小环境搭建实验    ▪Exchange2013增量备份    ▪OSSEC Monitor your App log file
▪《深入理解Nginx》阅读与实践(三):使用upstre...    ▪如何给Fedora 15创建磁盘分区    ▪Packet Sniffer Code in C using sockets
▪Error, some other host already uses address    ▪修改uCOS_II以实现“优先级+时间片”联合调度    ▪weblogic开发模式与生产模式介绍
▪Wireshark 高级特性    ▪ubuntu13.04版本下安装RabbitVCS,类似windows的Tortoi...    ▪Apache 一台主机绑定多个域名及虚拟主机
▪linux安全设置    ▪RHEL双网卡绑定    ▪Linux shell if参数
▪Windows配置路由时可以指定源地址啦    ▪centos安装vim7.4    ▪S3C2410 实验三——块拷贝、字拷贝(寄存器的...
▪系统运维——日志处理    ▪ip_conntrack缓存neighbour    ▪关键在封装并发出了帧-IP冲突也无所谓
▪weblogic11g 安装——linux 无图形界面    ▪《数据通信与网络》笔记--SCTP    ▪《数据通信与网络》笔记--TCP中的拥塞控制
▪weblogic11g 安装集群 —— win2003 系统、单台主...    ▪weblogic11g 节点管理器 nodemanager    ▪Citrix 服务器虚拟化之二十六 应用程序虚拟化...
▪如何将windows下的文件夹挂载到linux虚拟机下    ▪在64位AIX6.1下安装SAP JCo    ▪Outlook启动时提示“找不到文件Outlook.pst文件”...
▪weblogic8.1 登陆5 ip 限制    ▪weblogic 内存 及 内存溢出    ▪手把手教你在Windows端搭建Redmine项目管理软件
▪启动及重新启动nginx,重启nginx后丢失nginx.pid问...    ▪Win7实现快速启动栏并实现靠左边的终极操作...    ▪《深入理解Nginx》阅读与实践(二):配置项...
▪显示grub引导菜单    ▪nagios监控主机    ▪linux各种数据流重定向
▪centOS安装chrome浏览器    ▪Slackware 14 安装完全指南    ▪SharePoint 2013的100个新功能之内容管理(三)
▪Citrix 服务器虚拟化之二十一 桌面虚拟化之部...    ▪[问,ask]ubuntu13.04安装vncserver后只显示桌面,不显...    ▪Win7中IIS出现“HTTP 错误 404.17 - Not Found 请求的...
▪CentOS快速安装最新版本的SaltStack    ▪CentOS 6.4 快速安装Nginx笔记    ▪磁盘管理——RAID 0
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3