zoukankan      html  css  js  c++  java
  • 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
    ", 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)
    ", 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)
    ", 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!
    ");
        }
    
        ret = pthread_create(&mythread2, NULL, th2_handle, NULL);
        if (ret != 0) {
            printf("create thread failed!
    ");
        }
    
        sleep(3);
    
        ret = pthread_kill(mythread1, SIGUSR1);
        if (ret != 0) {
            printf("pthread_kill SIGUSR1 failed!
    ");
            exit(1);
        }
    
        ret = pthread_kill(mythread1, SIGUSR2);
        if (ret != 0) {
            printf("pthread_kill SIGUSR2 failed!
    ");
            exit(1);
        }
    
    
    
        ret = pthread_kill(mythread2, SIGUSR1);
        if (ret != 0) {
            printf("pthread_kill SIGUSR1 failed!
    ");
            exit(1);
        }
    
        sleep(1);
    
        ret = pthread_kill(mythread2, SIGUSR2);
        if (ret != 0) {
            printf("pthread_kill SIGUSR2 failed!
    ");
            exit(1);
        }
    
        ret = pthread_kill(mythread1, SIGKILL);
        if (ret != 0) {
            printf("pthread_kill SIGKILL failed!
    ");
            exit(1);
        }
    
        pthread_join(mythread1, NULL);
        pthread_join(mythread2, NULL);
        printf("main thread end!
    ");
        return 0;   
    }
    
  • 相关阅读:
    【特种兵系列】String中的==和equals()
    windows7 x64下maven安装和配置
    微信开发之本地接口调试(非80端口,无需上传服务器服务器访问)
    Java微信公众平台接口封装源码分享
    jdk安装
    用户权限管理
    Linux常用命令(一)
    Xshell显示中文乱码问题
    伪装虽易测试不易之微信浏览器
    每次新建项目出现appcompat_v7 解决方法
  • 原文地址:https://www.cnblogs.com/Sico2Sico/p/5384197.html
Copyright © 2011-2022 走看看