OS によって配信されたが、プロセスまたはスレッドによってブロックされている場合、シグナルは保留中です。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 可能であれば、他のメカニズムを使用します。アドバイスした。