Linux线程编程之信号处理
作者:网络转载 发布时间:[ 2015/1/22 13:57:33 ] 推荐标签:Linux 操作系统
本示例中,SigThread专用线程等待SIGUSR1信号。线程接收到该信号后,在互斥量的保护下修改全局标志gWorkFlag,然后调用pthread_cond_signal()唤醒WkrThread线程。WkrThread线程使用相同的互斥量检查全局标志的值,并原子地释放互斥量,等待条件发生。当条件满足时,该线程进入工作状态。
编译链接后,执行结果如下:
|
1 [wangxiaoyuan_@localhost~ ]$ ./Sigwait &
2 [1] 3940
3 [wangxiaoyuan_@localhost~ ]$ Worker thread starts!
4 kill -USR1 3940
5 Worker thread starts working...
6 [wangxiaoyuan_@localhost~ ]$ ps
7 PID TTY TIME CMD
8 3940 pts/12 00:00:31 Sigwait
9 4836 pts/12 00:00:00 ps
10 32206 pts/12 00:00:00 bash
11 [wangxiaoyuan_@localhost~ ]$ kill -KILL 3940
12 [wangxiaoyuan_@localhost~ ]$ ps
13 PID TTY TIME CMD
14 5664 pts/12 00:00:00 ps
15 32206 pts/12 00:00:00 bash
16 [1]+ Killed ./Sigwait
|
其中,命令kill -USR1和kill -KILL分别等同于kill -10和kill -9。
这种唤醒方式也可用于线程退出,而且比轮询方式高效。
3.4 示例4
本示例将sigwait()可用于主线程,即可正常捕捉信号,又不必考虑异步信号安全性。
1 int main(void)
2 {
3 //1. 创建工作线程(pthread_create)
4 //2. 等待终端键入的SIGINT信号(sigwait)
5 //3. 执行清理操作
6 //4. 程序退出(exit)
7 }
该例中主要等待SIGINT/SIGQUIT等终端信号,然后退出程序。
四 总结
Linux线程编程中,需谨记两点:1)信号处理由进程中所有线程共享;2)一个信号只能被一个线程处理。具体编程实践中,需注意以下事项:
不要在线程信号屏蔽字中阻塞、等待和捕获不可忽略的信号(不起作用),如SIGKILL和SIGSTOP。
不要在线程中阻塞或等待SIGFPE/SIGILL/SIGSEGV/SIGBUS等硬件致命错误,而应捕获它们。
在创建线程前阻塞这些信号(新线程继承信号屏蔽字),然后仅在sigwait()中隐式地解除信号集的阻塞。
不要在多个线程中调用sigwait()等待同一信号,应设置一个调用该函数的专用线程。
闹钟定时器是进程资源,且进程内所有线程共享相同的SIGALARM信号处理,故它们不可能互不干扰地使用闹钟定时器。
当一个线程试图唤醒另一线程时,应使用条件变量,而不是信号。

sales@spasvo.com