Я также рекомендовал бы использовать выбранные или некоторые другие несигнальные средства для завершения вашей нити. Одна из причин, по которой у нас есть темы, - попытаться уйти от сигнального безумия. Тем не менее ...
Обычно для передачи сигнала в поток используется 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);
}
QQQ, кажется, правильный ответ, который, к сожалению, имеет очень мало голосов. `pthread_cancel` - это решение вашей проблемы. – 2010-09-27 03:30:19
Пока поток остается заблокированным, он не может навредить. Проблема в том, что поток просыпается, когда вы закрываете все. Таким образом, исправление заключается в том, чтобы поместить некоторый код после строки, которая блокирует это, останавливает поток от выполнения чего-либо * else *, если завершение работы происходит. – 2011-09-28 17:15:12
Обсуждаются аналогичные проблемы и возможные решения: [Дескрипторы файлов и многопоточные программы] (http://www.ddj.com/hpc-high-performance-computing/212001285) – dmityugov 2008-11-10 12:58:48