私も、スレッドを終了するために選択またはその他の非シグナルベースの手段を使用することをお勧めします。スレッドがある理由の 1 つは、シグナルの狂気から逃れようとすることです。それは言った...
通常、pthread_kill() を SIGUSR1 または SIGUSR2 と共に使用して、スレッドにシグナルを送信します。他の提案されたシグナル (SIGTERM、SIGINT、SIGKILL) には、興味のないプロセス全体のセマンティクスがあります。
シグナルを送信したときの動作については、シグナルの処理方法に関係していると思います。ハンドラーがインストールされていない場合、そのシグナルのデフォルト アクションが適用されますが、シグナルを受信したスレッドのコンテキストで適用されます。したがって、たとえば、SIGALRM はスレッドによって「処理」されますが、その処理はプロセスの終了で構成されます。おそらく、望ましい動作ではありません。
スレッドによるシグナルの受信は、以前の回答で述べたように本当に中断できない状態でない限り、通常、EINTR を使用して読み取りから抜け出します。そうでないと、SIGALRM と SIGIO を使用した実験でプロセスが終了しなかったと思います。
あなたの読書はおそらくある種のループに入っていますか?読み取りが -1 return で終了した場合は、そのループから抜け出し、スレッドを終了します。
私の仮定をテストするためにまとめたこの非常にずさんなコードで遊ぶことができます-私は現時点でPOSIXの本から2、3タイムゾーン離れています...
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
int global_gotsig = 0;
void *gotsig(int sig, siginfo_t *info, void *ucontext)
{
global_gotsig++;
return NULL;
}
void *reader(void *arg)
{
char buf[32];
int i;
int hdlsig = (int)arg;
struct sigaction sa;
sa.sa_handler = NULL;
sa.sa_sigaction = gotsig;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
if (sigaction(hdlsig, &sa, NULL) < 0) {
perror("sigaction");
return (void *)-1;
}
i = read(fileno(stdin), buf, 32);
if (i < 0) {
perror("read");
} else {
printf("Read %d bytes\n", i);
}
return (void *)i;
}
main(int argc, char **argv)
{
pthread_t tid1;
void *ret;
int i;
int sig = SIGUSR1;
if (argc == 2) sig = atoi(argv[1]);
printf("Using sig %d\n", sig);
if (pthread_create(&tid1, NULL, reader, (void *)sig)) {
perror("pthread_create");
exit(1);
}
sleep(5);
printf("killing thread\n");
pthread_kill(tid1, sig);
i = pthread_join(tid1, &ret);
if (i < 0)
perror("pthread_join");
else
printf("thread returned %ld\n", (long)ret);
printf("Got sig? %d\n", global_gotsig);
}