多线程中的信号机制--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 ...
随机推荐
- 新建虚拟机_XP系统(二)
准备工作:按照<新建虚拟机_XP系统(一)>中操作步骤创建好虚拟机 1.启动虚拟机进入如下界面.新建分区.选择[6]运行DiskGenius工具 2.选择快速分区.可以自定义 3.新建分区 ...
- Java编程实现获取本机IP和计算机名的功能
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/wangshuxuncom/article/details/35990847 import java. ...
- Mint linux中调整屏幕亮度的方法
/********************************************************************* * Author : Samson * Date ...
- android 网络监测
public class NetWorkStateReceiver extends BroadcastReceiver { @Override public void onReceive(Contex ...
- Python3学习之路~2.1 列表、元组操作
列表 列表是我们以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作. 定义列表(list) names=['Amy','Bob','Cindy','David'] 通过下标访问列 ...
- Android中Activity的四种开发模式
Activity的四种启动模式:standard.singleTop.singleTask.singleInstance 清单文件中的Activity配置使用:android:launchMode ...
- 机器学习理论基础学习14.1---线性动态系统-卡曼滤波 Kalman filter
一.背景 动态模型 = 图 + 时间 动态模型有三种:HMM.线性动态系统(kalman filter).particle filter 线性动态系统与HMM的区别是假设相邻隐变量之间满足线性高斯分布 ...
- #C++初学记录(算法3)
C - 不要62 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer). 杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司 ...
- 《Convolutional Neural Network Architectures for Matching Natural Language Sentences》句子匹配
模型结构与原理 1. 基于CNN的句子建模 这篇论文主要针对的是句子匹配(Sentence Matching)的问题,但是基础问题仍然是句子建模.首先,文中提出了一种基于CNN的句子建模网络,如下图: ...
- yii2 restful api——app接口编程实例
<?php namespace common\components; use common\models\Cart; use common\models\User; use Yii; use y ...