日期:2014-05-16  浏览次数:20747 次

信号的传递和接收是否是线程安全的?
也就是说,本线程发送的信号,会被本线程接收到。

比如如下程序:(但又觉得这个程序并不能说明是这个命题)
#include <stdio.h>
#include <pthread.h>
#include <signal.h>

void
handle ()
{
  printf ("hallo thread %d.\n\n", pthread_self ());
}

void *
thr (void *arg)
{
  signal (SIGALRM, handle);
  printf ("thread %d send a SIGALRM.\n", pthread_self ());
  raise (SIGALRM);
}

int
main ()
{
  int threads = 5;
  pthread_t *pidp = alloca (sizeof (pthread_t) * threads);
  int i;

  for (i = 0; i < threads; ++i)
  {
  pthread_create (pidp + i, NULL, thr, NULL);
  }

  for (i = 0; i < threads; ++i)
  {
  pthread_join (*(pidp +i), NULL);
  }
}



------解决方案--------------------
信号的传递和接收不保证线程安全。但会保存现场。
在lz的程序上看,因为没有使用全局变量,因此在用户态看是线程安全的。
------解决方案--------------------
信号是发送给一个进程的, 进程内的每个线程都有自己的sigmask, 但是所有线程共享该进程的信号处理.
如果想发送某个信号到某个进程内的某个线程, 不要用raise/kill, 这是进程级的, 应该用pthread_kill
原型: int pthread_kill(pthread_t thread, int signo);

至于楼主所说的线程安全, 由于信号处理是共享的, 所以不能实现.
具体见APUE(2nd) page 333, 12.8 线程和信号.
------解决方案--------------------
用设计避开这种机制上的不足吧.