提高SIGINT,但卡在c中的线程中
我正在做一个利用线程的程序。我还有一个提高SIGINT,但卡在c中的线程中,c,linux,multithreading,signals,C,Linux,Multithreading,Signals,我正在做一个利用线程的程序。我还有一个SIGINT处理程序,可以正确地关闭所有内容,以便有序地关闭。但是,由于我的线程处于循环中,而(1)循环中,我的处理程序中的pthread\u join函数被卡住,我必须按ctrl+c多次才能单独关闭每个线程。我如何只需单击一次就可以做到这一点? 下面是我的线程辅助函数: void *worker(){ struct message msg; while(1){ if(wr.fnode != NULL){ sem_
SIGINT
处理程序,可以正确地关闭所有内容,以便有序地关闭。但是,由于我的线程处于循环中,而(1)
循环中,我的处理程序中的pthread\u join
函数被卡住,我必须按ctrl+c
多次才能单独关闭每个线程。我如何只需单击一次就可以做到这一点?
下面是我的线程辅助函数:
void *worker(){
struct message msg;
while(1){
if(wr.fnode != NULL){
sem_wait(&tsem);
stats->nptri++;
msg.patient = *(wr.fnode);
wr_deletefnode();
sem_post(&tsem);
sleep((float)(msg.patient.ttime/1000));
msgsnd(mqid,&msg,sizeof(msg)-sizeof(long),0);
}
}
}
这取决于您如何将
信号
(SIGINT或any)发送到线程
。要向线程发送信号,您应该使用pthread\u kill()
而不是kill()
或raise()
,因为信号处理程序(signal或sigaction
)只处理进程,而不是线程
int pthread_kill(pthread_t thread, int sig);
如果您试图使用kill命令/函数终止正在运行的线程,操作系统将抛出类似于警告:程序'/bin/bash'崩溃的警告。
在发送信号之前和之后,使用ps-eL | grep pts/0
观察正在运行的线程
我希望你能有所收获。你需要解决两件事:
如何打破无休止的while循环
如何从阻止系统调用返回(例如sem\u wait()
)
参考1.:
改变
while (1)
将来
while (!exit_flag)
全局定义退出标志
volatile sig_atomic_t exit_flag = 0;
并在接收到SIGINT
信号时将其设置为1
要捕获信号,请不要设置信号处理程序,而是使用sigwait()
创建一个单独的线程,以等待并接收SIGINT
确保所有其他线程都是通过阻塞SIGINT
创建的
参考2.:
通过记忆线程ID来跟踪所有正在运行的线程
在1中提到的信号侦听器线程之后。设置退出标志,然后逐个循环运行线程列表
- 使他们能够接收
SIGINT
- 使用
pthread\u kill()
向它们发送信号,如果它们被卡在系统调用中,调用会将设置errno
返回到EINTR
- 加入调用
pthread\u join()
的线程
如果线程位于它的工作中间,并且我希望/它需要在<代码>之前完成。有没有一种方法可以阻止或取消阻止线程接收特定信号?感谢您的回复。我以前没有尝试过,但您可以使用pthread\u cond\u signal()
它将解除对条件变量阻塞的线程的阻塞。检查手册页有这么多,你会得到。不要调用pthread_join?发布你的信号处理程序。“我还有一个SIGINT处理程序,它可以正确地关闭所有内容,以便有序地关闭。”听起来您可能是在信号处理程序中调用非异步信号安全函数,这是一种很好的进程死锁方法。谢谢您的回答。不幸的是,我需要使用一个处理器来捕捉我的信号,否则你的解决方案会更优雅。关于,exit_标志
部分。这不是在积极等待吗?我不知道这个词是否正确(我是从我自己的语言翻译过来的)。@jonelearn:“这不是在进行主动等待吗?”我不明白这个问题?如果需要使用信号处理程序,请在其内部设置exit_标志
,并在专用终止线程内部设置,如1所述。将对sigwait()
的调用替换为while(!exit_flag){sleep(1);}
。您输入了一个错误。应该是“确保创建了所有其他线程,阻止SIGINT
”@NominalAnimal:Hu!谢谢固定的。