首页 > 代码库 > C多线程编程信号处理

C多线程编程信号处理

用linux C编程的时候,处理信号在所难免。在多线程编程中需要注意两个函数的使用,一个是pthread_sigmask(), 用来在线程中屏蔽某个信号;另一个是sigaction(),在线程中用来设置信号的处理方式。

void sig_handler1(int arg)
{
  printf("thread1 get signal\n");
  return;
}
void sig_handler2(int arg)
{
  printf("thread2 get signal\n");
  return;
}

void *thread_fun1(void *arg)
{
  printf("new thread 1\n");

  struct sigaction act;
  memset(&act, 0, sizeof(act));
  sigaddset(&act.sa_mask, SIGQUIT);
  act.sa_handler = sig_handler1;
  sigaction(SIGQUIT, &act, NULL);

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


void *thread_fun2(void *arg)
{
  printf("new thread 2\n");

  struct sigaction act;
  memset(&act, 0, sizeof(act));
  sigaddset(&act.sa_mask, SIGQUIT);
  act.sa_handler = sig_handler2;
  sigaction(SIGQUIT, &act, NULL);

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

int main()
{
  pthread_t tid1, tid2;
  int err;
  int s;

  err = pthread_create(&tid1, NULL, thread_fun1, NULL);
  if(err != 0)
  {
    printf("create new thread 1 failed\n");
    return;
  }
  err = pthread_create(&tid2, NULL, thread_fun2, NULL);
  if(err != 0)
  {
    printf("create new thread 2 failed\n");
    return;
  }

  sleep(1);

  s = pthread_kill(tid1, SIGQUIT);
  if(s != 0)
  {
    printf("send signal to thread1 failed\n");
  }
  s = pthread_kill(tid2, SIGQUIT);
  if(s != 0)
  {
    printf("send signal to thread2 failed\n");
  }

  pthread_join(tid1, NULL);
  pthread_join(tid2, NULL);

  return 0;
  }

结果将会是:

new thread 2

new thread 1

thread1 get signal

或者:

new thread 1

new thread 2

thread2 get signal

会发现sig_handler打印的内容以最后注册的处理函数为准,意思是说线程1和线程2,在线程1中屏蔽SIGQUIT,而线程2中没有,按理来说不管运行多少遍最后处理函数打印出的内容都应该是thread2 get signal。但结果不是这样,为什么??

其实对某个信号处理函数,以程序执行时最后一次注册的处理函数为准,如果线程1最后执行,则以线程1注册的处理函数为准,最后线程2中处理函数替换为了线程1的。即在所有的线程里,同一个信号在任何线程里对该信号的处理一定相同 。

C多线程编程信号处理