我也會推薦使用選擇或其他一些非信號手段來終止你的線程。我們有線索的原因之一是嘗試擺脫信號瘋狂。這就是說...
通常一個人使用pthread_kill()與SIGUSR1或SIGUSR2向線程發送信號。其他建議的信號 - SIGTERM,SIGINT,SIGKILL - 具有您可能不感興趣的全過程語義。
至於發送信號時的行爲,我的猜測是它與如何處理你處理了信號。如果您沒有安裝處理程序,則會應用該信號的默認操作,但會在接收信號的線程的上下文中應用。因此,例如,SIGALRM將由您的線程「處理」,但處理將包括終止進程 - 可能不是期望的行爲。
線程接收到的信號通常會將其從EINTR讀取中分離出來,除非它確實處於前面回答中提到的那種不可中斷狀態。但我認爲這不是,或者您對SIGALRM和SIGIO的實驗不會終止這個過程。
您的閱讀也許在某種循環?如果讀取以-1返回終止,則跳出該循環並退出該線程。
你可以用這個非常草率的代碼,我放在一起測試一下我的假設玩 - 我是一對夫婦從時區,此刻我的POSIX的書拿走的......
#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);
}
來源
2008-10-15 08:29:21
bog
QQQ似乎有正確答案,不幸的是有極少數的選票。 `pthread_cancel`是解決您的問題的方法。 – 2010-09-27 03:30:19
只要線程仍然被阻塞,它不會造成任何傷害。問題是如果線程在你關閉的時候醒來。所以解決的辦法是在阻塞線之後放置一些代碼,以阻止線程執行任何操作*其他*如果正在關閉進程。 – 2011-09-28 17:15:12
類似的問題和可能的解決方案有討論:[文件描述符和多線程程序(http://www.ddj.com/hpc-high-performance-computing/212001285) – dmityugov 2008-11-10 12:58:48