Yo también recomendaría utilizar un medio de selección o algún otro medio no basado en señal para terminar su hilo. Una de las razones por las que tenemos hilos es tratar de alejarnos de la locura de la señal. Dicho esto ...
Generalmente se usa pthread_kill() con SIGUSR1 o SIGUSR2 para enviar una señal al hilo. Las otras señales sugeridas - SIGTERM, SIGINT, SIGKILL - tienen semántica en todo el proceso que puede que no le interese.
En cuanto al comportamiento cuando envió la señal, creo que tiene que ver con cómo manejaste la señal. Si no tiene ningún controlador instalado, se aplica la acción predeterminada de esa señal, pero en el contexto del hilo que recibió la señal. Por lo tanto, SIGALRM, por ejemplo, sería "manejado" por su hilo, pero el manejo consistiría en terminar el proceso, probablemente no en el comportamiento deseado.
El recibo de una señal por el hilo por lo general lo separará de una lectura con EINTR, a menos que esté realmente en ese estado ininterrumpible como se mencionó en una respuesta anterior. Pero creo que no, o sus experimentos con SIGALRM y SIGIO no habrían terminado el proceso.
¿Es su lectura tal vez en algún tipo de ciclo? Si la lectura termina con -1 return, salga de ese ciclo y salga del hilo.
Se puede jugar con este código muy descuidado que arme para poner a prueba mis suposiciones - Soy un par de zonas horarias de distancia de mis libros POSIX en el momento ...
#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 parece tener la respuesta correcta, que desafortunadamente tiene muy pocos votos. 'pthread_cancel' es la solución a su problema. –
Mientras el hilo permanezca bloqueado, no puede hacer daño. El problema es si el hilo se despierta mientras estás cerrando las cosas. Entonces, la solución es poner un código después de la línea que bloquea que impida que el hilo haga algo * else * si hay un cierre en progreso. –
Un problema similar y posibles soluciones se discuten allí: [Descriptores de archivos y programas multiproceso] (http://www.ddj.com/hpc-high-performance-computing/212001285) – dmityugov