桃源谷

心灵的旅行

人生就是一场旅行,不在乎旅行的目的地,在乎的是沿途的风景和看风景的心情 !
posts - 32, comments - 42, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

准则1:不依赖于信号收发的设计

Posted on 2008-06-01 20:27 lymons 阅读(1356) 评论(0)  编辑 收藏 引用 所属分类: C++CUnix/Linux文章翻译
From 2008精选

[C++] UNIX上的C++程序设计守则(1)

原文:http://d.hatena.ne.jp/yupo5656/20040712/p1

Unix跟Windows等那些”对于开发者易于使用”的OS比起来,在信号和线程的利用方面有诸多的限制。但是即使不知道这些知识就做构架设计和实现的情况也随处可见。这个就是那些经常不能再现的bug的温床吧。

因此,我想分成几回来写一些准则来防止陷入到这些圈套里。

准则1:不依赖于信号收发的设计

·给其他进程以及自己发送异步信号并改变处理流程的设计不要做

  •  异步信号是值用kill系统调用来创建?发送的信号、例如SIGUSR1,SIGUSR2,SIGINT,SIGTERM 等
  • 简单的使用忽略信号(SIG_IGN)则没有问题

·不要把线程和信号一起使用 

  • 这将使程序动作的预测和调试变得很困难

 

说明:

同步信号是指,因为某些特定的操作*1而引起向自身进程发送某些特定的信号,例如SIGSEGV,SIGBUS,SIGPIPE,SIGSYS,SIGILL,SIGFPE。异步信号就是这些以外的信号。在什么时机发送异步信号并不能被预测出来。我们会在程序里追加收到某些信号时做一些特殊处理(信号处理函数)的函数。那么根据收到的信号就跳到信号处理函数的程序就叫做”在任意代码处都能发生跳转”的程序。这样的程序往往隐藏这下面的那些问题:

  1. 容易引入BUG。”任意的代码”虽然也包含”执行C/C++里面的一条语句的过程中”的意思,但这很容易跳出程序员的正常思维以及默认的假定条件。编写程序的时候往往需要考虑比C++异常分支还要多得多的分支情况。
  2. 使测试项目激增。即使根据白盒测试达成100%的分支覆盖,也不能网罗到因为接受信号而发生的跳转分支处理。也就是说做到100%的网罗信号跳转分支的测试是不能全部实现的。一般的,加上要考虑” 在实行某个特定代码时因为接受到信号而发生的误操作”这样的BUG会经常发生*2的这种情况,测试困难往往就是导致软件的品质低下的诱因。

 

根据经验,”当检查到子进程结束(接收到SIGCHLD信号)时,要做必要的处理”像这样的信号处理不管做什么都是有必要的情况会有,但是除此以外的信号处理,例如

  • 把自己的状态用信号告诉其他进程
  • 主线程在输入输出函数里发送信号给被阻塞的子线程,并解除阻塞

等,是应该事先好好好好考虑过后再去做实际的实现。前者的话,如果不强制在”普通的”进程间进行通信的话可能会很好,后者是特意要使用线程,也要应该按照即使阻塞了也不能发生问题那样再设计。

不管怎么样,如果必须要使用信号的话,也要先全部*3理解这些陷阱以及,和多线程软件设计的场合一样或者说比它更严格的制约.注意事项都需要铭记在心里。

*1:例如,引用空指针

*2:参照 id:yupo5656:20040703 的sigsafe说明

*3:暂时先掌握”准则2”:-)


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


我的个人简历第一页 我的个人简历第二页