Linux _ pthread 线程 信号

线程的信号

  1. 线程的信号与进程之间的关系
    线程没有自己独立的信号机制。
    线程的信号依赖与所在的进程。
    线程有自己的“信号屏蔽集合”,使得:
    1)各线程可以向其同进程内的线程发送信号。(使用pthread_kill
    2)各线程可以设置几的“信号屏蔽集合”,其初值从创建线程中继承。
    信号屏蔽集合类似与进程的信号屏蔽字,
    但它只作用于该线程。
    使用pthread_sigmask(类似于进程的sigprocmask函数)
    3)各线程共享对某信号的处理方法,
    即收到信号后,各线程执行相同的处理函数。
    除非该信号被该线程屏蔽。

    注意:进程收到能够“终止”该进程的信号后,该进程里的所有线程都将终止。

  2. 向线程发送信号
    pthread_kill
    原型:int pthread_kill (pthread_t thread, int sig);
    参数:sig, 如果为0,则检测对应的线程thread是否存在

  3. 设置线程的信号屏蔽集合
    pthread_sigmask
    原型: int pthread_sigmask(int how,
    const sigset_t *restrict set,
    sigset_t *restrict oset);
    注意:用法和sigprocmask相似。

    注意:SIGKILL和SIGSTOP,对进程和线程都不能屏蔽。

    1. 实例
      主线程中,分别创建两个线程
      在线程1中,屏蔽SIGUSR2之外的所有信号。即仅对其开放SIGUSR2
      设置SIGUSR1的信号处理函数
      在线程2中,设置SIGUSR2的信号处理函数
      在主线程中,分别向线程1发送SIGUSR1、SIGUSR2信号
      分别向线程2发送SIGUSR1、SIGUSR2信号
      最后,向线程1发送SIGKILL信号。
      main5.c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void sigusr_handle (int arg)
{
    printf("thread(id=%u) catch signal %d\n", pthread_self(), arg);
}

void * th1_handle(void *arg)
{
    int i;

    sigset_t set;
    sigfillset(&set);
    sigdelset(&set, SIGUSR2);
    pthread_sigmask(SIG_SETMASK, &set, 0);

    signal(SIGUSR1, sigusr_handle);

    for (i=0; i<5; i++) {
        printf("this is in thread 1(id=%u)\n", pthread_self());
        pause();
    }
}

void * th2_handle(void *arg)
{
    int i;
    signal(SIGUSR2, sigusr_handle);
    for (i=0; i<5; i++) {
        printf("this is in thread 2(id=%u)\n", pthread_self());
        pause();
    }
}


int main(void)
{   
    pthread_t mythread1, mythread2; 
    int ret;

    ret = pthread_create(&mythread1, NULL, th1_handle, NULL);
    if (ret != 0) {
        printf("create thread failed!\n");
    }

    ret = pthread_create(&mythread2, NULL, th2_handle, NULL);
    if (ret != 0) {
        printf("create thread failed!\n");
    }

    sleep(3);

    ret = pthread_kill(mythread1, SIGUSR1);
    if (ret != 0) {
        printf("pthread_kill SIGUSR1 failed!\n");
        exit(1);
    }

    ret = pthread_kill(mythread1, SIGUSR2);
    if (ret != 0) {
        printf("pthread_kill SIGUSR2 failed!\n");
        exit(1);
    }



    ret = pthread_kill(mythread2, SIGUSR1);
    if (ret != 0) {
        printf("pthread_kill SIGUSR1 failed!\n");
        exit(1);
    }

    sleep(1);

    ret = pthread_kill(mythread2, SIGUSR2);
    if (ret != 0) {
        printf("pthread_kill SIGUSR2 failed!\n");
        exit(1);
    }

    ret = pthread_kill(mythread1, SIGKILL);
    if (ret != 0) {
        printf("pthread_kill SIGKILL failed!\n");
        exit(1);
    }

    pthread_join(mythread1, NULL);
    pthread_join(mythread2, NULL);
    printf("main thread end!\n");
    return 0;   
}
posted @ 2016-04-02 11:38  夜色下的港湾  Views(1583)  Comments(0Edit  收藏  举报