Chinaunix首页 | 论坛 | 博客
  • 博客访问: 550561
  • 博文数量: 156
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1183
  • 用 户 组: 普通用户
  • 注册时间: 2013-11-22 11:42
文章分类

全部博文(156)

文章存档

2015年(67)

2014年(89)

分类: 嵌入式

2015-05-07 21:53:35

一、发送信号的函数
    int pthread_kill(pthread_t thread, int sig);
    1、别被名字吓到,pthread_kill可不是kill,而是向线程发送signal。还记得signal吗,大部分signal的默认动作是终止进程的运行,所以,我们才要用sigaction()去抓信号并加上处理函数。

    2、向指定ID的线程发送sig信号,如果线程代码内不做处理,则按照信号默认的行为影响整个进程,也就是说,如果你给一个线程发送了SIGQUIT,但线程却没有实现signal处理函数,则整个进程退出。如果要获得正确的行为,就需要在线程内实现sigaction了。所以,如果int sig的参数不是0,那一定要清楚到底要干什么,而且一定要实现线程的信号处理函数,否则,就会影响整个进程。如果int sig是0呢,这是一个保留信号,其实并没有发送信号,作用是用来判断线程是不是还活着。

二、信号处理
    1、进程信号处理:
    int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
    给信号signum设置一个处理函数,处理函数在sigaction中指定
        act.sa_mask 信号屏蔽字
        act.sa_handler 信号集处理程序

    2、信号集的处理
    int sigemptyset(sigset_t *set); 清空信号集
    int sigfillset(sigset_t *set);  将所有信号加入信号集
    int sigaddset(sigset_t *set, int signum); 增加一个信号到信号集
    int sigdelset(sigset_t *set, int signum); 删除一个信号到信号集

    3、多线程信号屏蔽处理
    /* int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)*/这是进程的信号屏蔽处理

    int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset);
         how = SIG_BLOCK:向当前的信号掩码中添加set,其中set表示要阻塞的信号组。
         SIG_UNBLOCK:向当前的信号掩码中删除set,其中set表示要取消阻塞的信号组。
         SIG_SETMASK:将当前的信号掩码替换为set,其中set表示新的信号掩码。
    在多线程中,新线程的当前信号掩码会继承创造它的线程的信号掩码
    一般情况下,被阻塞的信号将不能中断此线程的执行,除非此信号的产生是因为程序运行出错如 SIGSEGV;另外不能被忽略处理的信号 SIGKILL 和 SIGSTOP 也无法被阻塞。

三、手册
PTHREAD_KILL(3)            Linux Programmer’s Manual           PTHREAD_KILL(3)
NAME
       pthread_kill - send a signal to a thread
        //pthread_kill向线程发送一个信号

SYNOPSIS
       #include
        //包含头文件signal.h

       int pthread_kill(pthread_t thread, int sig);

       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.
        //pthread_kill向同一进程中的另一个发送信号,这个信号异步的发送到线程

       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.
        //如果信号是0,实际并没有信号发送,这可以用来测试指定的线程ID是否存在

RETURN VALUE
       On success, pthread_kill() returns 0; on error, it returns an error number, and no signal is sent.
        //如果成功返回0,失败就返回错误码,没有信号发送

ERRORS
       ESRCH  No thread with the ID thread could be found.
        //没有指定的线程ID可以找到

       EINVAL An invalid signal was specified.
        //发送的信号是无效的

CONFORMING TO
       POSIX.1-2001.

NOTES
       Signal  dispositions  are  process-wide:  if  a  signal  handler is installed, the handler will be invoked in the thread
       thread, but if the disposition of the signal is "stop", "continue", or "terminate", this action will  affect  the  whole
       process.
        //进程中所有的线程对用一个信号使用同一个信号处理函数。如果信号处理函数被设置,它将会唤醒指定的线程。但如果信号是“stop”、
        //“continue”、“terminate”,将会影响整个进程

SEE ALSO
       kill(2) sigaction(2), sigpending(2), pthread_self(3), pthread_sigmask(3), raise(3), pthreads(7), signal(7)

COLOPHON
       This  page  is part of release 3.22 of the Linux man-pages project.  A description of the project, and information about
       reporting bugs, can be found at


PTHREAD_SIGMASK(3)         Linux Programmer’s Manual        PTHREAD_SIGMASK(3)
NAME
       pthread_sigmask - examine and change mask of blocked signals
       //检测或者改变信号的掩码   

SYNOPSIS
       #include
        //包含头文件

       int pthread_sigmask(int how, 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 that its use in multithreaded programs
       is explicitly specified by POSIX.1-2001.  Other differences are noted in this page.
          //pthread_sigmask() 像sigprocmask(2)一样,不同的地方是这个函数使用在多吸纳成环境中

       For a description of the arguments and operation of this function, see sigprocmask(2).
          //想看更详细的资料,去看手册sigprocmask(2)

RETURN VALUE
       On success, pthread_sigmask() returns 0; on error, it returns an error number.
          //成功返回0,失败返回错误码

ERRORS
       See sigprocmask(2).
          //错误码参照sigprocmask(2)

CONFORMING TO
       POSIX.1-2001.

NOTES
       A new thread inherits a copy of its creator’s signal mask.
        //一个新线程继承创造它的那个线程的掩码

四、实例

点击(此处)折叠或打开

  1. /*DATE:            2015-3-31
  2.  *AUTHOR:        WJ
  3.  *DECRIPTION:    正确到处理信号

  4.  *    int pthread_kill(pthread_t thread, int sig);
  5.  *        向线程thread发送sig信号,成功返回0,失败返回错误码
  6.  *
  7.  *    int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
  8.  *        为信号signum设置处理函数,处理函数在sigaction中指定
  9.  *        act.sa_mask 信号屏蔽字
  10.  *        act.sa_handler 信号集处理程序
  11.  *
  12.  * int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset);
  13.  *        多线程信号屏蔽函数
  14.  *        how = SIG_BLOCK:向当前的信号掩码中添加set,其中set表示要阻塞的信号组。
  15.  *        SIG_UNBLOCK:向当前的信号掩码中删除set,其中set表示要取消阻塞的信号组。
  16.  * SIG_SETMASK:将当前的信号掩码替换为set,其中set表示新的信号掩码。
  17.  * 在多线程中,新线程的当前信号掩码会继承创造它的线程的信号掩码
  18.  */
  19. #include "apue.h"

  20. void sig_handler1(int arg)
  21. {
  22.     printf("thread1 get signal\n");
  23.     return;
  24. }
  25. void sig_handler2(int arg)
  26. {
  27.     printf("thread2 get signal\n");
  28.     return;
  29. }

  30. void *thread_fun1(void *arg)
  31. {
  32.     printf("new thread 1\n");

  33.     struct sigaction act;
  34.     memset(&act, 0, sizeof(act));
  35.     sigaddset(&act.sa_mask, SIGQUIT);
  36.     act.sa_handler = sig_handler1;
  37.     sigaction(SIGQUIT, &act, NULL);

  38.     pthread_sigmask(SIG_BLOCK, &act.sa_mask, NULL);
  39.     sleep(2);
  40. }


  41. void *thread_fun2(void *arg)
  42. {
  43.     printf("new thread 2\n");

  44.     struct sigaction act;
  45.     memset(&act, 0, sizeof(act));
  46.     sigaddset(&act.sa_mask, SIGQUIT);
  47.     act.sa_handler = sig_handler2;
  48.     sigaction(SIGQUIT, &act, NULL);

  49. //    pthread_sigmask(SIG_BLOCK, &act.sa_mask, NULL);
  50.     sleep(2);
  51. }

  52. int main()
  53. {
  54.     pthread_t tid1, tid2;
  55.     int err;
  56.     int s;

  57.     err = pthread_create(&tid1, NULL, thread_fun1, NULL);
  58.     if(err != 0)
  59.     {
  60.         printf("create new thread 1 failed\n");
  61.         return;
  62.     }
  63.     err = pthread_create(&tid2, NULL, thread_fun2, NULL);
  64.     if(err != 0)
  65.     {
  66.         printf("create new thread 2 failed\n");
  67.         return;
  68.     }

  69.     sleep(1);

  70.     s = pthread_kill(tid1, SIGQUIT);
  71.     if(s != 0)
  72.     {
  73.         printf("send signal to thread1 failed\n");
  74.     }
  75.     s = pthread_kill(tid2, SIGQUIT);
  76.     if(s != 0)
  77.     {
  78.         printf("send signal to thread2 failed\n");
  79.     }

  80.     pthread_join(tid1, NULL);
  81.     pthread_join(tid2, NULL);

  82.     return 0;
  83. } 






阅读(1189) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~