博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POSIX 线程 – pthread_sigmask
阅读量:5236 次
发布时间:2019-06-14

本文共 4678 字,大约阅读时间需要 15 分钟。

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

概念

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

  pthread_sigmask

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

  pthread_kill 和 sigwait

===============================================================================        #include 
#include
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, 0)!= 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

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/jingzhishen/p/3468856.html

你可能感兴趣的文章
CAN总线波形中ACK位电平为什么会偏高?
查看>>
MyBatis课程2
查看>>
桥接模式-Bridge(Java实现)
查看>>
svn客户端清空账号信息的两种方法
查看>>
springboot添加servlet的两种方法
查看>>
java的Array和List相互转换
查看>>
layui父页面执行子页面方法
查看>>
如何破解域管理员密码
查看>>
Windows Server 2008 R2忘记管理员密码后的解决方法
查看>>
IE11兼容IE8的设置
查看>>
windows server 2008 R2 怎么集成USB3.0驱动
查看>>
Foxmail:导入联系人
查看>>
vue:axios二次封装,接口统一存放
查看>>
vue中router与route的区别
查看>>
js 时间对象方法
查看>>
网络请求返回HTTP状态码(404,400,500)
查看>>
Spring的JdbcTemplate、NamedParameterJdbcTemplate、SimpleJdbcTemplate
查看>>
Mac下使用crontab来实现定时任务
查看>>
303. Range Sum Query - Immutable
查看>>
图片加载失败显示默认图片占位符
查看>>