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

linux信号量

2013年04月23日 ⁄ 综合 ⁄ 共 1318字 ⁄ 字号 评论关闭

1. 什么是不可靠信号

信号可能丢失

2. 什么是信号屏蔽

信号有信号产生和信号传递两个步骤,如果设置了信号屏蔽,那么被设置的信号可以产生,但不会被传递。但撤销该信号屏蔽后,就会把先前的已经产生的传递到相应地方,不过如果先前该信号产生了多次,最终也只会传递一次。有了信号屏蔽,这样就可以保证在进行信号处理时,不会丢失该信号的再次产生。

3. 信号处理的相关api

Void *Singal(int signo, void (*func)(int);//线程不安全

Int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);//线程不安全

Int sigaction(int signo, const struct sigaction *restrict act, strcut sigaction *restrict oact);

4. 别用Signal,用sigaction

可以通过signal或者sigaction函数来设置信号处理函数,但signal函数太过古老,因此推荐使用sigaction。理由如下:

Ø sigaction可以提供更多接收到信号的信息。

Ø 调用完信号处理函数后重新设置处理函数不会对sigaction有影响,因为sigaction默认是不会去重置处理函数的,同时在执行处理函数会屏蔽掉该信号,也不会有竞争。

Ø signal函数在某些系统中会默认重启被中断的系统调用,而sigaction默认不会这样做。

Ø signal函数在多线程环境中的行为是未定义的,必须使用sigaction函数。

5. 信号,多进程,多线程

Ø Fork出的子进程继承父进程的信号处理方式,因为子进程开始时复制了父进程的存储映像,所以信号捕捉函数的地址在子进程中是有意义的。

Ø Exec函数将原先设置为要捕捉的信号都更改为它们的默认动作。

Ø 每个线程都有自己的信号屏蔽字,但是信号的处理是所有线程共享的。

6. SIGHUP信号与控制终端

UNIX中进程组织结构为 session (会话)包含一个前台进程组及一个或多个后台进程组,一个进程组包含多个进程。一个session可能会有一个session首进程,而一个session首进程可能会有一个控制终端。一个进程组可能会有一个进程组首进程。进程组首进程的进程ID与该进程组ID相等。这儿是可能会有,在一定情况之下是没有的。与终端交互的进程是前台进程,否则便是后台进程。

SIGHUP会在以下3种情况下被发送给相应的进程:

1、终端关闭时,该信号被发送到session首进程以及作为job提交的进程(即用 & 符号提交的进程)

2、session首进程退出时,该信号被发送到该session中的前台进程组中的每一个进程

3、若父进程退出导致进程组成为孤儿进程组,且该进程组中有进程处于停止状态(收到SIGSTOP或SIGTSTP信号),该信号会被发送到该进程组中的每一个进程。

系统对SIGHUP信号的默认处理是终止收到该信号的进程。所以若程序中没有捕捉该信号,当收到该信号时,进程就会退出。

解决办法a、自己在程序里屏蔽sighup信号;b、使用nohup

7. 内核实现

参考《深入理解linux内核》

抱歉!评论已关闭.