哪个线程处理信号?
- 2024-11-14 08:30:00
- admin 原创
- 19
问题描述:
我有 2 个线程(线程 1 和线程 2)。并且我有 的信号处理SIGINT
。每当SIGINT
发生时,线程 2 都应该处理信号。为此,我编写了以下程序
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
void sig_hand(int no) //signal handler
{
printf("handler executing...
");
getchar();
}
void* thread1(void *arg1) //thread1
{
while(1) {
printf("thread1 active
");
sleep(1);
}
}
void * thread2(void * arg2) //thread2
{
signal(2, sig_hand);
while(1) {
printf("thread2 active
");
sleep(3);
}
}
int main()
{
pthread_t t1;
pthread_t t2;
pthread_create(&t1, NULL, thread1, NULL);
pthread_create(&t2, NULL, thread2, NULL);
while(1);
}
我编译并运行该程序。每 1 秒打印一次“thread1 active”,每 3 秒打印一次“thread2 active”。
现在我生成了SIGINT
。但它打印“thread1 active”和“thread2 active”消息,如上所示。我再次生成SIGINT
,现在每 3 秒只打印“thread2 active”消息。我再次生成SIGINT
,现在所有线程都被阻止了。
所以我理解了,第一次主线程执行信号处理程序。第二次线程 1 执行处理程序,最后线程 2 执行信号处理程序。
我怎样才能编写代码,就像每当信号发生时,只有线程 2 必须执行我的信号处理程序?
解决方案 1:
如果向某个进程发送一个信号,那么该进程中的哪个线程将处理该信号是不确定的。
根据pthread(7)
:
POSIX.1 还要求线程共享一系列其他属性(即,这些属性是整个进程的而不是每个线程的):
......
信号处置
......
POSIX.1 区分了指向整个进程的信号和指向单个线程的信号的概念。根据 POSIX.1,指向进程的信号(
kill(2)
例如,使用 发送)应由进程内任意选择的单个线程处理。
如果您希望进程中有一个专用线程来处理某些信号,这里有一个示例向pthread_sigmask(3)
您展示如何操作:
下面的程序在主线程中阻止一些信号,然后创建一个专用线程通过 sigwait(3) 获取这些信号。以下 shell 会话演示了它的用法:
$ ./a.out &
[1] 5423
$ kill -QUIT %1
Signal handling thread got signal 3
$ kill -USR1 %1
Signal handling thread got signal 10
$ kill -TERM %1
[1]+ Terminated ./a.out
程序源
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
/* Simple error handling functions */
#define handle_error_en(en, msg) \n do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
static void *
sig_thread(void *arg)
{
sigset_t *set = arg;
int s, sig;
for (;;) {
s = sigwait(set, &sig);
if (s != 0)
handle_error_en(s, "sigwait");
printf("Signal handling thread got signal %d
", sig);
}
}
int
main(int argc, char *argv[])
{
pthread_t thread;
sigset_t set;
int s;
/* Block SIGQUIT and SIGUSR1; other threads created by main()
will inherit a copy of the signal mask. */
sigemptyset(&set);
sigaddset(&set, SIGQUIT);
sigaddset(&set, SIGUSR1);
s = pthread_sigmask(SIG_BLOCK, &set, NULL);
if (s != 0)
handle_error_en(s, "pthread_sigmask");
s = pthread_create(&thread, NULL, &sig_thread, (void *) &set);
if (s != 0)
handle_error_en(s, "pthread_create");
/* Main thread carries on to create other threads and/or do
other work */
pause(); /* Dummy pause so we can test program */
}
解决方案 2:
仔细阅读signal(7) & pthread(7) & pthread_kill(3) & sigprocmask(2) & pthread_sigmask(3) - 您可以使用它们(阻止SIGINT
不需要的线程)。另请阅读pthread 教程。
避免使用信号在线程间进行通信或同步。例如,考虑互斥体(pthread_mutex_lock等...)和条件变量(pthread_cond_wait等...)。
如果其中一个线程运行事件循环(例如围绕poll(2) ...)请考虑使用signalfd(2)。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件