Linux线程编程之信号处理
作者:网络转载 发布时间:[ 2015/1/22 13:57:33 ] 推荐标签:Linux 操作系统
|
1 //定义USE_SIGWAIT时
2 --Thread b7f316c0 Received Signal 3(Quit)! //Ctrl+
3 sigwait returns 0(Success), signo = 2 //Ctrl+C
4 //未定义USE_SIGWAIT时
5 --Thread b7fb66c0 Received Signal 3(Quit)! //Ctrl+
6 sigwaitinfo returns -1(Interrupted system call), signo = 0
|
对比可见,sigwaitinfo()可被等待信号集以外的信号中断,而sigwait()不会被中断。
3.2 示例2
本示例测试多线程中,sigwait()和sigwaitinfo()函数对信号的同步等待。
|
1 void *SigMgrThread(void *pvArg)
2 {
3 pthread_detach(pthread_self());
4
5 //捕获SIGQUIT信号,以免程序收到该信号后退出
6 signal(SIGQUIT, sighandler);
7
8 //使用创建线程时的pvArg传递信号屏蔽字
9 int dwRet;
10 while(1)
11 {
12 #ifdef USE_SIGWAIT
13 int dwSigNo;
14 dwRet = sigwait((sigset_t*)pvArg, &dwSigNo);
15 if(dwRet == 0)
16 SigHandler(dwSigNo);
17 else
18 printf("sigwait() failed, errno: %d(%s)!
", dwRet, strerror(dwRet));
19 #else
20 siginfo_t tSigInfo;
21 dwRet = sigwaitinfo((sigset_t*)pvArg, &tSigInfo);
22 if(dwRet != -1) //dwRet与tSigInfo.si_signo值相同
23 SigHandler(tSigInfo.si_signo);
24 else
25 {
26 if(errno == EINTR) //被其他信号中断
27 printf("sigwaitinfo() was interrupted by a signal handler!
");
28 else
29 printf("sigwaitinfo() failed, errno: %d(%s)!
", errno, strerror(errno));
30 }
31 }
32 #endif
33 }
34
35 void *WorkerThread(void *pvArg)
36 {
37 pthread_t tThrdId = pthread_self();
38 pthread_detach(tThrdId);
39
40 printf("Thread %x starts to work!
", (unsigned int)tThrdId);
41 //working...
42 int dwVal = 1;
43 while(1)
44 dwVal += 5;
45 }
46
47 int main(void)
48 {
49 printf("Main thread %x is running!
", (unsigned int)pthread_self());
50
51 //屏蔽SIGUSR1等信号,新创建的线程将继承该屏蔽字
52 sigset_t tBlockSigs;
53 sigemptyset(&tBlockSigs);
54 sigaddset(&tBlockSigs, SIGRTMIN);
55 sigaddset(&tBlockSigs, SIGRTMIN+2);
56 sigaddset(&tBlockSigs, SIGRTMAX);
57 sigaddset(&tBlockSigs, SIGUSR1);
58 sigaddset(&tBlockSigs, SIGUSR2);
59 sigaddset(&tBlockSigs, SIGINT);
60
61 sigaddset(&tBlockSigs, SIGSEGV); //试图阻塞SIGSEGV信号
62
63 //设置线程信号屏蔽字
64 pthread_sigmask(SIG_BLOCK, &tBlockSigs, NULL);
65
66 signal(SIGINT, sighandler); //试图捕捉SIGINT信号
67
68 //创建一个管理线程,该线程负责信号的同步处理
69 pthread_t tMgrThrdId;
70 pthread_create(&tMgrThrdId, NULL, SigMgrThread, &tBlockSigs);
71 printf("Create a signal manager thread %x!
", (unsigned int)tMgrThrdId);
72 //创建另一个管理线程,该线程试图与tMgrThrdId对应的管理线程竞争信号
73 pthread_t tMgrThrdId2;
74 pthread_create(&tMgrThrdId2, NULL, SigMgrThread, &tBlockSigs);
75 printf("Create another signal manager thread %x!
", (unsigned int)tMgrThrdId2);
76
77 //创建一个工作线程,该线程继承主线程(创建者)的信号屏蔽字
78 pthread_t WkrThrdId;
79 pthread_create(&WkrThrdId, NULL, WorkerThread, NULL);
80 printf("Create a worker thread %x!
", (unsigned int)WkrThrdId);
81
82 pid_t tPid = getpid();
83 //向进程自身发送信号,这些信号将由tMgrThrdId线程统一处理
84 //信号发送时若tMgrThrdId尚未启动,则这些信号将一直阻塞
85 printf("Send signals...
");
86 kill(tPid, SIGRTMAX);
87 kill(tPid, SIGRTMAX);
88 kill(tPid, SIGRTMIN+2);
89 kill(tPid, SIGRTMIN);
90 kill(tPid, SIGRTMIN+2);
91 kill(tPid, SIGRTMIN);
92 kill(tPid, SIGUSR2);
93 kill(tPid, SIGUSR2);
94 kill(tPid, SIGUSR1);
95 kill(tPid, SIGUSR1);
96
97 int dwRet = sleep(1000);
98 printf("%d seconds left to sleep!
", dwRet);
99
100 ThreadKill(WkrThrdId, 0); //不建议向已经分离的线程发送信号
101
102 sleep(1000);
103 int *p=NULL; *p=0; //触发段错误(SIGSEGV)
104
105 return 0;
106 }
|
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
Linux下开源的DDR压力测试工具曝Linux恶意软件:让树莓派设备挖掘数字货币linux系统中不同颜色的文件夹及根目录介绍软件测试工程师必知必会Linux命令Linux下DNS服务器配置如何成为不可替代的Linux运维工程师?详解Linux进程(作业)的查看和杀死Linux 日志定时轮询流程详解比特币勒索病毒不只Windows系统有,Linux版的来了Linux日志定时轮询流程详解Linux iommu和vfio概念空间解构Linux系统如何低于TCP洪水攻击Linux无损调整分区大小Linux下防火墙配置实例Linux使用Jexus托管Asp.Net Core应用程序Linux中引号的那些事

sales@spasvo.com