http://www.cnblogs.com/qq78292959/archive/2012/04/05/2432985.html

概念

  • 按照 POSIX, 异步 (外部) 信号发送到整个进程.
  • 所有线程共享同一个设置, 即通过 sigaction 设置的线程处置方法.
  • 每个线程有自己的信号掩码, 线程库根据该掩码决定将信号发送到哪个线程.
  • 由于 Linux 线程实现上的独特性, 外部信号始终发送到特定的线程.

pthread_sigmask

  • pthread_sigmask 用来定义线程的信号掩码
  • 其接口与 sigprocmask 一样
    ===============================================================================
    #include <pthread.h>
    #include <signal.h> int pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask);
    ===============================================================================

pthread_kill 和 sigwait

===============================================================================
#include <pthread.h>
#include <signal.h> int pthread_kill (pthread_t thread, int signo);
int sigwait (const sigset_t *set, int *sig);
===============================================================================
#define ESRCH 3 /* No such process */
  • pthread_kill 向特定的线程发送信号.请在创建的线程中使用signal(SIGKILL,sig_handler)处理信号,如果你给一个线程发送了SIGQUIT,但线程却没有实现signal处理函数,则整个进程退出。

    if(pthread_kill(pid, )!= ESRCH)
        {
            printf("thread %d exists!\n", pid);
            pthread_kill(pid, SIGQUIT);
    //        pthread_exit(NULL);//this won't work
            printf("after kill\n");
        }

  • sigwait 暂定调用线程, 直到 set 中定义的某个信号递达调用线程.
  • sigwait 返回时, sig 中保存的是接收到的信号编号.
  • sigwait 所等待的信号必须在所有线程中阻塞, 而不仅仅是调用线程. 在多线程的程序里,希望只在主线程中处理信号,可以使用

函数:

int pthread_sigmask (int how,

const sigset_t *set,

sigset_t *oset)

用作在主调线程里控制信号掩码。

注:新的信号屏蔽字由参数set指定,而原先的信号屏蔽字将保存到信号集oset中

How:

SIG_BLOCK:     结果集是当前集合参数集的并集(把参数set中的信号添加到信号屏蔽字中)
SIG_UNBLOCK: 结果集是当前集合参数集的差集(把信号屏蔽字设置为参数set中的信号)
SIG_SETMASK: 结果集是由参数集指向的集(从信号屏蔽字中删除参数set中的信号)

头文件: <signal.h>

错误:   [EINVAL] how不是已定义值
提示:   除非信号在所有的线程里都阻塞,否则总能将异步信号传输给这个进程。

例子:

#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(30);

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 */

rc = pthread_sigmask(SIG_BLOCK, &mask, NULL);

if (rc != 0)

{

printf("%d, %s\n", rc, strerror(rc));

return NULL;

}

rc = sleep(15);

if (rc != 0)

{

printf("Masked thread %lu did not get expected results! "

"rc=%d \n", tid, rc);

return NULL;

}

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(3);

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;

}

程序返回:

Enter Testcase - ./pthread_sigmask_test

Set up the alarm handler for the process

Create masked and unmasked threads

Thread 3086597040 entered

Masked thread 3076107184 entered

Thread 3065617328 entered

Masked thread 3055127472 entered

Thread 3044637616 entered

Masked thread 3034147760 entered

Send a signal to masked and unmasked threads

Wait for masked and unmasked threads to complete

Thread 3086597040 in signal handler

Thread 3086597040 did not get expected results! rc=27

Thread 3065617328 in signal handler

Thread 3065617328 did not get expected results! rc=27

Thread 3044637616 in signal handler

Thread 3044637616 did not get expected results! rc=27

Masked thread 3076107184 completed masked work

Masked thread 3055127472 completed masked work

Masked thread 3034147760 completed masked work

Main completed

												

POSIX 线程 – pthread_sigmask的更多相关文章

  1. Posix线程编程指南(3) 线程同步

    互斥锁 尽管在Posix Thread中同样可以使用IPC的信号量机制来实现互斥锁mutex功能,但显然semphore的功能过于强大了,在Posix Thread中定义了另外一套专门用于线程同步的m ...

  2. Posix线程编程指南

    Posix线程编程指南 Posix线程编程指南... 1 一线程创建与取消... 2 线程创建... 2 1.线程与进程... 2 2. 创建线程... 2 3. 线程创建属性... 2 4. 创建的 ...

  3. Posix线程编程指南(3)

    这是一个关于Posix线程编程的专栏.作者在阐明概念的基础上,将向您详细讲述Posix线程库API.本文是第三篇将向您讲述线程同步. 一.互斥锁尽管在Posix Thread中同样可以使用IPC的信号 ...

  4. Posix线程编程指南(5) 杂项

    在Posix线程规范中还有几个辅助函数难以归类,暂且称其为杂项函数,主要包括pthread_self().pthread_equal()和pthread_once()三个,另外还有一个LinuxThr ...

  5. Posix线程编程指南(4) 线程终止

    线程终止方式 一般来说,Posix的线程终止有两种情况:正常终止和非正常终止.线程主动调用pthread_exit()或者从线程函数中return都将使线程正常退出,这是可预见的退出方式:非正常终止是 ...

  6. Posix线程编程指南(2) 线程私有数据

    概念及作用 在单线程程序中,我们经常要用到"全局变量"以实现多个函数间共享数据.在多线程环境下,由于数据空间是共享的,因此全局变量也为所有线程所共有.但有时应用程序设计中有必要提供 ...

  7. POSIX 线程详解 一种支持内存共享的简捷工具

    线程是有趣的 了解如何正确运用线程是每一个优秀程序员必备的素质.线程类似于进程.如同进程,线程由内核按时间分片进行管理.在单处理器系统中,内核使用时间分片来模拟线程的并发执行,这种方式和进程的相同.而 ...

  8. posix 线程(一):线程模型、pthread 系列函数 和 简单多线程服务器端程序

    posix 线程(一):线程模型.pthread 系列函数 和 简单多线程服务器端程序 一.线程有3种模型,分别是N:1用户线程模型,1:1核心线程模型和N:M混合线程模型,posix thread属 ...

  9. 通用线程:POSIX 线程详解,第 3 部分 条件互斥量(pthread_cond_t)

    使用条件变量提高效率 本文是 POSIX 线程三部曲系列的最后一部分,Daniel 将详细讨论如何使用条件变量.条件变量是 POSIX 线程结构,可以让您在遇到某些条件时“唤醒”线程.可以将它们看作是 ...

随机推荐

  1. 你的C/C++程序为什么无法运行?揭秘Segmentation fault (1)

    什么让你对C/C++如此恐惧? 晦涩的语法?还是优秀IDE的欠缺? 我想那都不是问题,最多的可能是一个类似这样的错误: 段错误(Segmentation fault) 这是新手无法避免的错误,也是老手 ...

  2. java linux 项目常常无故被关闭 进程无故消息

    布了几个项目.竟然天天会自己主动的挂掉.急了.花时间攻克了一下.总结方案例如以下: 1.磁盘满了.这大家都懂,清一下 2.tomcat在关闭的或是重新启动的时候,经常后台进程没有被关闭.须要用ps a ...

  3. 浅析Windows系统调用——2种切换到内核模式的方法

    http://shayi1983.blog.51cto.com/4681835/1710861/

  4. c3p0、dbcp、proxool、BoneCP比较

    1.1 测试环境: 操作系统:windows xp sp3 数据库:mysql 5.1 1.2 测试条件: initialSize=30; maxSize=200; minSize=30; 其余参数为 ...

  5. JQuery实战--能够编辑的表格

    廊坊下雪了.15年的第二场雪.比14的来的稍晚一些.停靠在11教门前的自行车.成了廊坊师范学院最漂亮的风景线.还记得以前学习css的时候.就以前接触过怎样编写设计一些表格和表单的样式,比如怎样设计表格 ...

  6. Javascript时间以及格式化秒

    var now = new Date(); timer = $.timer(timeout, function () {     var sec_num = Math.ceil((now.getTim ...

  7. 近看到的机器学习、NLP相关书单

    书单再多,不去读,也是白搭~~ 水木上的machine learning书单:http://www.newsmth.net/bbscon.php?bid=5&id=34859&ftyp ...

  8. UEFI+GPT引导基础篇 :什么是GPT,什么是UEFI?

    GUID Partition Table (GPT) is a standard for the layout of the partition table on a physical storage ...

  9. 第六章 字节码执行方式--解释执行和JIT

    注:主要参考自<分布式java应用:基础与实践><深入理解Java虚拟机(第二版)> 1.两种执行方式: 解释执行(运行期解释字节码并执行) 强制使用该模式:-Xint 编译为 ...

  10. go语言基础之数组比较和赋值

    1.go语音基础之数组比较和赋值 示例: package main //必须有个main包 import "fmt" func main() { //支持比较,只支持 == 或 ! ...