信号正在等待它是由操作系统交付的,但是一个进程或线程有被阻止了它。如果你没有阻止SIGUSR1,那么它将被交付,并且SIGUSR1的默认处置是终止该进程。你的sigpending
在这种情况下什么也不做;它被有效地绕过。无论是SIGUSR1首先与pthread_sigmask
或(可选)处理它。
总之这是一个可疑的设计。对于阻塞/签署代码,根据SECONDS设置的时间长短,您仍然可能需要等待很长时间才能让线程循环发现它是关闭的时间。如果你真的想为此使用信号,我会建议建立一个设置开关的信号处理程序。当SIGUSR1交付时,处理程序将被调用,它设置开关,sleep
将被信号中断,您检查EINTR并立即循环检查开关,然后执行pthread_exit
。
选项1(在Linux编译)
#define _POSIX_C_SOURCE 2
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <signal.h>
void* foo(void* arg)
{
sigset_t set, isSignal, allSigs;
sigfillset(&allSigs);
if (sigprocmask(SIG_SETMASK, &allSigs, NULL) == -1)
{
printf("sigprocmask: %m\n");
exit(1);
}
sigemptyset(&set);
if (sigaddset(&set, SIGUSR1) == -1)
{
printf("sigaddset: %m\n");
exit(1);
}
while (1)
{
if (sigpending(&isSignal) != 0)
{
printf("sigpending: %m\n");
exit(1);
}
else
if (sigismember(&isSignal, SIGUSR1))
{
printf("signal pending for thread, exiting\n");
break;
}
printf("Doing groovy thread stuff...\n");
sleep(2);
}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t tid;
int rc;
rc = pthread_create(&tid, NULL, foo, NULL);
if (rc)
{
printf("pthread_create: %m\n");
exit(1);
}
sleep(10);
pthread_kill(tid, SIGUSR1);
pthread_join(tid, NULL);
}
选项2(在Linux编译)
#define _POSIX_C_SOURCE 2
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <signal.h>
volatile int stop = 0;
void handler(int sig)
{
stop = 1;
}
void* foo(void* arg)
{
signal(SIGUSR1, handler); //use sigaction, i'm too lazy here
while (! stop)
{
printf("Doing groovy thread stuff...\n");
if (sleep(4) > 0)
if (errno == EINTR)
{
printf("sleep interrupted, exiting thread...\n");
continue;
}
}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t tid;
int rc;
rc = pthread_create(&tid, NULL, foo, NULL);
if (rc)
{
printf("pthread_create: %m\n");
exit(1);
}
sleep(10);
pthread_kill(tid, SIGUSR1);
pthread_join(tid, NULL);
}
选项3使用,如果你能一些其他机制。建议。
谢谢你,选项2对我来说真的很好,我同意,当EINTR时我打断睡眠并退出是很好的。我非常喜欢这个解决方案,谢谢! – user1777907