多线程中的信号机制--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 ...
随机推荐
- Spring Data JPA(官方文档翻译)
关于本书 介绍 关于这本指南 第一章 前言 第二章 新增及注意点 第三章 项目依赖 第四章 使用Spring Data Repositories 4.1 核心概念 4.2 查询方法 4.3 定义rep ...
- idea 创建的maven+spring+mybatis项目整合 报错无法创建bean
报错如下: Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with n ...
- Roadblocks--poj3255(次短路)
题目链接 求次短路的问题: dist[i][0]和dist[i][1]表示从起点1到i的距离和从起点n到i的距离: 次短路要比最短路大但小于其他路: 每条路1--n的距离都可以用dist[i][0] ...
- 洛谷P2679 子串 [noip2015] dp
正解:dp 解题报告: 感觉是道dp好题啊,所以就写了个题解 代码实现难度低,思维难度大,像我这种思维僵化傻逼选手只想到了爆搜+组合数学... 其实是道很妙的dp题!好趴也没有多妙主要大概是妙在想到了 ...
- BZOJ4614 UVA1742 Oil 计算几何+搜索+扫描线
正解:计算几何+搜索+扫描线 解题报告: 传送门 哇我是真的觉得这题很妙了!各个方面都很妙啊... 首先有一个很重要的结论:最优线一定可以通过各种变换(旋转/平移)使得经过一条线段的左端点(...并不 ...
- epoll详细工作原理(转)
原文:没有找到出处 开发高性能网络程序时,windows开发者们言必称iocp,linux开发者们则言必称epoll.大家都明白epoll是一种IO多路复用技术,可以非常高效的处理数以百万计的sock ...
- 查看win信任的证书办法机构(CA机构的公钥)
cmd mmc
- 自增ID时如何插入ID
自增ID时如何插入ID SET IDENTITY_INSERT TABLE_NAME ON; INSERT INTO TABLE_NAME(XXX, XXX,..., XXX) SELECT XXX, ...
- 高性能MySQL中的三星索引
高性能MySQL中的三星索引 我对此提出了深深的疑问: 一星:相关的记录指的是什么??(相关这个词很深奥,“相关部门”是什么部门) 二星:如果建立了B-Tree(B+Tree)索引,数据就有序了.三星 ...
- Session实例
Session常用方法(一) session对象用来保存一些在与每个用户回话期间需要保存的数据信息,这样就方便了回话期间的一些处理程序.如可以用session变量记住用户的用户名,以后就不必在其他的网 ...