多线程中的信号机制--signwait()函数【转】
本文转载自:http://blog.csdn.net/yusiguyuan/article/details/14237277
在Linux的多线程中使用信号机制,与在进程中使用信号机制有着根本的区别,可以说是完全不同。在进程环境中,对信号的处理是,先注册信号处理函数,当信号异步发生时,调用处理函数来处理信号。它完全是异步的(我们完全不知到信号会在进程的那个执行点到来!)。然而信号处理函数的实现,有着许多的限制;比如有一些函数不能在信号处理函数中调用;再比如一些函数read、recv等调用时会被异步的信号给中断(interrupt),因此我们必须对在这些函数在调用时因为信号而中断的情况进行处理(判断函数返回时 enno 是否等于 EINTR)。
- sigwait - wait for a signal
- #include <signal.h>
- int sigwait(const sigset_t *set, int *sig);
- Description
- The sigwait() function suspends execution of the calling thread until the delivery of one
- of the signals specified in the signal set set. The function accepts the signal (removes
- it from the pending list of signals), and returns the signal number insig.
- The operation of sigwait() is the same as sigwaitinfo(2), except that:
- * sigwait() only returns the signal number, rather than a siginfo_t structure describing
- the signal.
- * The return values of the two functions are different.
- Return Value
- On success, sigwait() returns 0. On error, it returns a positive error number.
- pthread_sigmask - examine and change mask of blocked signals
- #include <signal.h>
- int pthread_sigmask(inthow, const sigset_t *set, sigset_t *oldset);
- Compile and link with -pthread.
- DESCRIPTION
- The pthread_sigmask() function is just like sigprocmask(2), with the difference thatits use
- in multithreaded programs is explicitly specified by POSIX.1-2001.
- Other differences are noted in this page.
- For a description of the arguments and operation of this function, see sigprocmask(2).
- RETURN VALUE
- On success, pthread_sigmask() returns 0; on error, it returns an error number.
- NOTES
- A new thread inherits a copy of its creator's signal mask.
- (from man sigprocmask: )
- The behavior of the call is dependent on the value of how, as follows.
- SIG_BLOCK
- The set of blocked signals is the union of the current set and the set argument.
- SIG_UNBLOCK
- The signals in set are removed from the current set of blocked signals. It is permissible
- to attempt to unblock a signal which is not blocked.
- SIG_SETMASK
- The set of blocked signals is set to the argument set.
- If oldset is non-NULL, the previous value of the signal mask is stored inoldset.
- If set is NULL, then the signal mask is unchanged (i.e.,how is ignored), but the current
- value of the signal mask is nevertheless returned inoldset (if it is not NULL).
- #include <signal.h>
- int pthread_kill(pthread_tthread, intsig);
- Compile and link with -pthread.
- DESCRIPTION
- The pthread_kill() function sends the signal sig to thread, another thread in the same
- process as the caller. The signal is asynchronously directed to thread.
- If sig is 0, then no signal is sent, but error checking is still performed; this can be
- used to check for the existence of a thread ID.
- RETURN VALUE
- On success, pthread_kill() returns 0; on error, it returns an error number, and no signal
- is sent.
- ERRORS
- ESRCH No thread with the ID thread could be found.
- EINVAL An invalid signal was specified.
- #include <pthread.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <signal.h>
- #include <errno.h>
- /* Simpleerror handling functions*/
- #define handle_error_en(en, msg)\
- do { errno= en; perror(msg);exit(EXIT_FAILURE);}while(0)
- static void *
- sig_thread(void*arg)
- {
- sigset_t *set=(sigset_t*) arg;
- int s, sig;
- for (;;){
- s = sigwait(set,&sig);
- if (s != 0)
- handle_error_en(s,"sigwait");
- printf("Signal handling thread got signal %d\n", sig);
- }
- }
- int
- main(int argc, char*argv[])
- {
- pthread_t thread;
- sigset_t set;
- int s;
- /*
- Block SIGINT; other threads created by main() will inherit
- a copy of the signal mask.
- */
- sigemptyset(&set);
- sigaddset(&set, SIGQUIT);
- sigaddset(&set, SIGUSR1);
- s = pthread_sigmask(SIG_BLOCK,&set,NULL);
- if (s!= 0)
- handle_error_en(s,"pthread_sigmask");
- s = pthread_create(&thread,NULL,&sig_thread,(void*)&set);
- if (s!= 0)
- handle_error_en(s,"pthread_create");
- /*
- Main thread carries on to create other threads and/ordo
- other work
- */
- pause();/* Dummy pause so we can test program*/
- return 0;
- }
- digdeep@ubuntu:~/pthread/learnthread$ gcc-Wall-pthread-o pthread_sigmask pthread_sigmask.c
- digdeep@ubuntu:~/pthread/learnthread$./pthread_sigmask&
- [1] 4170
- digdeep@ubuntu:~/pthread/learnthread$ kill-QUIT%1
- digdeep@ubuntu:~/pthread/learnthread$ Signal handling thread got signal 3
- digdeep@ubuntu:~/pthread/learnthread$ kill-USR1%1
- digdeep@ubuntu:~/pthread/learnthread$ Signal handling thread got signal 10
- digdeep@ubuntu:~/pthread/learnthread$ kill-TERM%1
- digdeep@ubuntu:~/pthread/learnthread$
- [1]+ Terminated./pthread_sigmask
- digdeep@ubuntu:~/pthread/learnthread$
- #include <pthread.h>
- #include <stdio.h>
- #include <sys/signal.h>
- #define NUMTHREADS 3
- void sighand(int signo);
- void *threadfunc(void *parm)
- {
- pthread_t tid = pthread_self();
- int rc;
- printf("Thread %u entered\n", tid);
- rc = sleep(3);
- printf("Thread %u did not get expected results! rc=%d\n", tid, rc);
- return NULL;
- }
- void *threadmasked(void *parm)
- {
- pthread_t tid = pthread_self();
- sigset_t mask;
- int rc;
- printf("Masked thread %lu entered\n", tid);
- sigfillset(&mask); /* Mask all allowed signals */
- // sigemptyset(&mask);
- rc = pthread_sigmask(SIG_BLOCK, &mask, NULL);
- if (rc != 0)
- {
- printf("%d, %s\n", rc, strerror(rc));
- return NULL;
- }
- rc = sleep(1);
- if (rc != 0)
- {
- printf("Masked thread %lu did not get expected results! ""rc=%d \n",tid, rc);
- return NULL;
- }
- // sigwait(&mask,&rc);
- printf("Masked thread %lu completed masked work\n",tid);
- return NULL;
- }
- int main(int argc, char **argv)
- {
- int rc;
- int i;
- struct sigaction actions;
- pthread_t threads[NUMTHREADS];
- pthread_t maskedthreads[NUMTHREADS];
- printf("Enter Testcase - %s\n", argv[0]);
- printf("Set up the alarm handler for the process\n");
- memset(&actions, 0, sizeof(actions));
- sigemptyset(&actions.sa_mask);
- actions.sa_flags = 0;
- actions.sa_handler = sighand;
- rc = sigaction(SIGALRM,&actions,NULL);
- printf("Create masked and unmasked threads\n");
- for(i=0; i<NUMTHREADS; ++i)
- {
- rc = pthread_create(&threads[i], NULL, threadfunc, NULL);
- if (rc != 0)
- {
- printf("%d, %s\n", rc, strerror(rc));
- return -1;
- }
- rc = pthread_create(&maskedthreads[i], NULL, threadmasked, NULL);
- if (rc != 0)
- {
- printf("%d, %s\n", rc, strerror(rc));
- return -1;
- }
- }
- sleep(5);
- printf("Send a signal to masked and unmasked threads\n");
- for(i=0; i<NUMTHREADS; ++i)
- {
- rc = pthread_kill(threads[i], SIGALRM);
- rc = pthread_kill(maskedthreads[i], SIGALRM);
- }
- printf("Wait for masked and unmasked threads to complete\n");
- for(i=0; i<NUMTHREADS; ++i) {
- rc = pthread_join(threads[i], NULL);
- rc = pthread_join(maskedthreads[i], NULL);
- }
- printf("Main completed\n");
- return 0;
- }
- void sighand(int signo)
- {
- pthread_t tid = pthread_self();
- printf("Thread %lu in signal handler\n",tid);
- return;
- }
(ps:由上面的几篇文章可知,线程中的信号处理机制和进程中的信号处理机制是不同的,或者说是完全不同的,一般在多线程中使用信号的,或单独启动一个线程类处理信号,在主进程中发送信号,在主进程中使用了pthread_mask()函数来处理信号屏蔽信息,这个时候在主进程中使用kill,这个时候线程也是可以接受到信号的原因是pthread_mask继承了主进程的信号屏蔽信息,这个时候也是可以在使用pthread_kill给相应的线程发送相应的信号,但是在有的程序中,在线程中使用pthread_mask,这个使用就必须使用pthread_kill来发送信号了;但是在进程中的信号机制没有这么复杂,进程中只需要注册一个函数,就静静的等待信号处理。不过在进程中使用的方法也是可以在线程中使用的)
多线程中的信号机制--signwait()函数【转】的更多相关文章
- Linux内核中的信号机制--一个简单的例子【转】
本文转载自:http://blog.csdn.net/ce123_zhouwei/article/details/8562958 Linux内核中的信号机制--一个简单的例子 Author:ce123 ...
- linux中的信号机制
概述 Linux信号机制是在应用软件层次上对中断机制的一种模拟,信号提供了一种处理异步事件的方法,例如,终端用户输入中断键(ctrl+c),则会通过信号机制停止一个程序[1]. 这其实就是向那个程序( ...
- Qt在多线程中使用信号槽的示例
之前对线程理解得不深入,所以对Qt的线程机制没有搞清楚,今天写一篇文章总结一下,如有错误,欢迎指出. 首先需要理解线程是什么,线程在代码中的表现其实就是一个函数,只不过这个函数和主线程的函数同时运行, ...
- java中的异常处理机制_函数覆盖时的异常特点
/*注意:异常声明在函数上 异常在子父类覆盖时的体现1.子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者异常的子类2.如果父类方法抛出多个异常,那么子类在覆盖该方法 ...
- Rust多线程中的消息传递机制
代码说话. use std::thread; use std::sync::mpsc; use std::time::Duration; fn main() { let (tx, rx) = mpsc ...
- linux信号机制与python信号量
1.信号本质 软中断信号(signal,又简称为信号)用来通知进程发生了异步事件.在软件层次上是对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的.信号是进程间 ...
- Linux信号机制
Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...
- 处理python中的信号
什么是信号 信号(signal)-- 进程间通讯的一种方式,也可作为一种软件中断的方法.一个进程一旦接收到信号就会打断原来的程序执行来按照信号进行处理. 简化术语,信号是一个事件,用于中断运行功能的执 ...
- Qt多线程编程中的对象线程与函数执行线程
近来用Qt编写一段多线程的TcpSocket通信程序,被其中Qt中报的几个warning搞晕了,一会儿是说“Cannot create children for a parent that is in ...
随机推荐
- css3的一个小demo(箭头hover变化)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- MongoDB的"副本“数据库服务器
1.假设1数据库服务器为活跃服务器(主服务器),2和3为备份服务器,当1出现故障的时候,那么会在2和3中推选出一个(根据权重的等规则)作为活跃服务器,而当1又恢复正常了之后呢,它将以备份服务器的身份出 ...
- 棋盘问题---poj1321(dfs)
http://poj.org/problem?id=1321 由于搜索是原来写的,而集训的时候没来所以只能现在补补咯-_- 简单的深搜 #include<stdio.h> #include ...
- Kubernetes网络的4种解决方案
一.Kubernetes + Flannel Kubernetes的网络模型假定了所有Pod都在一个可以直接连通的扁平的网络空间中,这在GCE(Google Compute Engine)里面是现成的 ...
- CF750F New Year and Finding Roots 构造+树论
正解:构造 解题报告: 传送门! 交互题交互题!哇好新鲜啊QwQ 首先考虑最傻逼的做法,应该是每个人都能想到的 首先看一下它给的条件,考虑到完全二叉树的性质,就可以发现,如果给的邻居只有一个,说明是叶 ...
- WordPress跳过语言包加载提高效率
WordPress 加载语言包是需要花费 0.1-0.5 秒不等的时间,所以如果 WordPress 前台可以不加载语言包,而主题中的一些文本直接写成中文,就可以加快网站的速度,并且又能保证后台的中文 ...
- InnoSQL/MySQL并行复制的实现与配置
InnoSQL/MySQL并行复制的实现与配置 http://www.innomysql.net/article/6276.html 并行复制之前的解决方案 InnoSQL在5.5.30-v4版本中支 ...
- inter x86 emulator accelerator(HAXM installer) not compatible with windows
在SDK manager中遇到如下错误:这将导致AVD后期运行和启动方面的问题. 解决办法: 在如下的网址里面下载haxm-windows_v6_2_0这个文件的压缩包,自己手动安装即可.网站如下:点 ...
- How many Fibs?(poj 2413)大数斐波那契
http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=259#problem/C Description Recall the defi ...
- PAT 1024 Palindromic Number[难]
A number that will be the same when it is written forwards or backwards is known as a Palindromic Nu ...