现在的位置: 首页 > 综合 > 正文

Linux信号解决的问题及其遇到的问题

2013年09月04日 ⁄ 综合 ⁄ 共 1357字 ⁄ 字号 评论关闭

        这里要记录linux信号问题,引入信号是为了解决什么问题,以及引入之后带来的新问题,有没有解决办法,在遇到时不断更新吧,注定是一个持久战!

        1、SIGALARM信号,alarm信号可以设计一个计时器,每个进程只能有一个闹钟时钟,这个限制决定了,当一个进程多次调用alarm函数时,最后一个alarm设置的时钟会覆盖前面设置的时钟。记住这个限制,这个限制引入了新的问题,这个问题的另外的描述是,(这是《unix环境高级编程》里提到的问题)

        一,如果在调用alarm之前,进程已经设置了alarm函数,那么本次alarm怎样在不覆盖前次alarm的基础上继续工作?

        二,之前的signal(SIGALARM,function)函数设置的处理函数和本次不一样,那么本次signal函数怎样在不覆盖前次信号处理函数的基础上继续工作呢?

         解决上面两个问题的办法 是,一,alarm函数的返回值是上次alarm的剩余值,如果该值小于本次设置的值,则应等到上次设置的闹钟超时;如果大于本次设置的值,则应保存该值,在函数处理结束前回复该值;二,signal的返回值,要么是SIG_ERR,要么是前次信号处理的函数指针,同样在注册函数时,保存上次函数,在函数处理结束前回复原来的值。

         SIGALARM的默认动作是终止进程。设置SIGALARM信号是为了给调用者一个闹钟,应用的场所一般是在低速设备阻塞时,例如read/write,设置alarm函数可以防止系统长期阻塞,但这里有一个问题就是,在alarm(nsec)和read()之间有一个竞争关系,如果在read()之前调用了alarm()函数,那么read()还是会长期阻塞。

          解决这个问题可以通过setjmp和longjmp函数来解决,因为setjmp设置的时候返回0,longjmp可以设置不同的返回值,可以将read函数包裹在setjmp = 0里面,这样如果处理函数里面的longjmp跳转了也不会出现上面的问题了。书中也说sigprocmask和sigsuspend也可以解决问题。

          三、但是这里也有一个问题,如果同时又两个信号存在时,当一个信号在处理函数中,而另一个信号插进来,后一个信号可以中断前一个信号的处理过程。这就是书中说的信号处理程序交互问题。

          四、最后需要提到的问题是,自动重启动函数,系统中有些函数在遇到某些信号时,它是内部设置了自动重启动机制的,这可以阻止函数因为信号中断处理的问题。

          为了解决上面三、四的问题,可以选择使用sigaction()函数来取代signal()函数,sigaction()函数在处理信号函数期间,对其他后面的信号采取了阻塞的处理,就是说后来的信号都在信号队列里面排队,当然如果连续多个相同的信号,当解除阻塞后也只当做一个信号处理。

          sigaction()函数里面的参数struct sigaction里面有一个参数sa_flag值,可以设置SA_INTERPUPT标识,这样就使系统调用被中断后不再重启动。这个参数同样可以设置自动重启动功能,就是设置为SA_RESTART标识。

抱歉!评论已关闭.