在LINUX中,线程(thread)可以看成是共享相同地址空间的多个进程。虽然线程共用同一个进程号,但每个线程有自己唯一的线程号和线程栈。实际上,除了每个进程有私有的地址空间之外,线程和普通进程没有本质区别。
信号是一种常见的通信机制。内核可以向进程发送信号表示特定的事件发生,进程间也可以通过kill函数互相发送信号。发送信号时,发送方需要指定对方进程的进程号。那如果在线程之间发送信号呢?
Linux系统提供了专门的函数pthread_kill来发送信号给某个线程。需要注意的是,进程内部的线程共享信号处理。如果我们希望线程能对某个信号作出响应,必须捕捉该信号。否则,该信号的默认处理会影响整个进程。
下面给出在线程中响应SIGUSR1信号的实例代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
void handler(int signo)
{
printf("catch signal\n");
}
void *thread_function(void *arg)
{
while ( 1 ) pause();
}
int main()
{
int ret;
pthread_t a_thread;
signal(SIGUSR1, handler);
if ((ret = pthread_create(&a_thread, NULL, thread_function, NULL)) != 0)
{
printf("fail to pthread_create : %s\n", strerror(ret));
exit(-1);
}
sleep(1);
pthread_kill(a_thread, SIGUSR1);
printf("press enter to continue\n");
getchar();
return 0;
}
pthread_kill函数还可以用来检测某个线程是否存在,参考代码如下
if ((ret = pthread_kill(a_thread, 0)) == 0) // 信号0用来检查是否有错误
{
printf("thread does exist!\n");
}
else if (ret == ESRCH)
{
printf("thread does not exist\n");
}
此外,还可以设定线程中的信号掩码sigmask来影响信号的行为,读者可自行查看相关帮助信息。