zoukankan      html  css  js  c++  java
  • c++上下文使用信号小结

    说明:本文的上下文环境是 unix/linux操作系统,g++编译环境, gdb调试环境。


    signal是 阻塞模式的良好搭挡。一些需要低速调用的程序,例如 socket、oracle连接,若工作在非阻塞模式下,轮询会有大量的CPU开销,而阻塞模式则使得程序不能及时处理那些需要实时响应的操作。signal可以将程序从阻塞状态唤醒,以处理紧急事件,然后再做别的事情。

    unix_program_advance 一书中第十章,详细地介绍了 unix 系统提供的信号捕获函数。

    在开发中应注意:

    1、确定要使用阻塞还是非阻塞。oci和 socket中,默认都是阻塞的。

    在socket 中,可以使用  fcntl()来设置O_NONBLOCK, O_NDELAY.

    if (fcntl(fd, F_SETFL, orig_flags | O_NONBLOCK) < 0
    {
        
    }

    在oci中,可以使用 OCIAttrSet()函数的 OCI_ATTR_NONBLOCKING_MODE 属性值来设置oci的操作为非阻塞模式。详细的用法见 Oracle Call Interface Programmer's Guide  B10779-01. chapter 2 中 Nonblocking Mode in OCI 一节。

    当socket为阻塞模式时,可以使用 setsockopt来设置 recv的超时时间。

    1、任何一个可能无限阻塞的调用,调用之间加一个alarm()

    在oracle中,如果在呼叫 oracle时网络掉线。则函数会永远阻塞。所以,有必要在可能阻塞的函数前,加一个alarm()以在超时后将其唤醒。

    下面示例了信号的使用。当函数调用超过3秒后,跳出函数并重新连接数据库以执行此操作。直到操作三次仍不能成功,则放弃操作。

    do
    {
        alarm(
    3);
        
    if(  table.query() == false && errno == EINTR ) 
        {
            conndb();
        }
        
    else
        {
         
    break;
        }
    }
    while (retryTimes < 3)

    alarm(0);

    2、用 sigaction() 而不是 signal() 来设置信号钩子。signal()跨平台性能不好。在 linux下跑得很健壮的程序,到了 hp-unix或 ibm-aix上表现得非常糟糕,而 solaris上 signal 又有不同的表现。较于 signal, sigaction 定义了被中断的低速调用是否重新唤起 ( 默认不唤起);sigactionl() 还有屏蔽功能,这使得信号处理函数可以专注地处理当前的信号。

    3、当前信号处理函数结束前要唤起先前定义的信号处理函数。

    sigaction( signo, NULL, oldHandle );

    4、可以设置捕获所有的信号,以避免程序收到信号时意外退出。信号编号下界限为1,最高界限是SIGMAX,可以使用for()循环设置钩子。

    5、子进程会继承父进程的信号钩子,但不能继承父进程中已经设置的信号(例如,闹钟信号)。

    6、如果想在收到信号后跳出当前的上下文环境,用  throw()。

    相关资料 :

    1、 <the design of the unix operationg system>第 7.2 信号  从操作系统实现的角度,详细地介绍了信号的分类、信号如何被唤醒、信号在什么情况下会丢失或引发意外。(注 : 书中讨论的内容是 原始版本的 signal(),实际上, sigaction 已经解决了信号丢失、信号异常的问题。)

    2、<Advanced Programming in the UNIX Environment>  第 10章详细介绍了不可靠信号signal、可靠信号sigaction在 posix.1、SVR4、4.3+BSD中,信号的实现。并给出了对信号进行处理的相关源码。

    使用信号的完整示例:

    信号一个极有用的使用是:将进程从阻塞状态唤醒。
    信号有一定的局限性。信号不能像 message 那样传递消息结构,而只能传递一个简单的信号。
    信号会破坏程序的流程。因为我们不知道信号究竟什么时候会发生。
    一个比较合理的处理办法是:
    当进程收到关注的信号时,执抛出一个异常。这样,程序可以根据自己的意愿想停就停,想开就开。
    示例如下:


    范晨鹏
    ------------------
    软件是一种态度
    成功是一种习惯


  • 相关阅读:
    (原)Lazarus 异构平台下多层架构思路、DataSet转换核心代码
    (学)新版动态表单研发,阶段成果3
    (学) 如何将 Oracle 序列 重置 清零 How to reset an Oracle sequence
    (学)XtraReport WebService Print 报错
    (原)三星 i6410 刷机 短信 无法 保存 解决 办法
    (原) Devexpress 汉化包 制作工具、测试程序
    linux下网络配置
    apache自带ab.exe小工具使用小结
    Yii::app()用法小结
    PDO使用小结
  • 原文地址:https://www.cnblogs.com/diylab/p/1297542.html
Copyright © 2011-2022 走看看