У меня небольшие проблемы с нитями. По сути, я хочу поймать SIGINT и очистить все потоки и выйти. Что у меня есть (скелетный код):
main.c:
sig_atomic_t running;
void handler(int signal_number)
{
running = 0;
}
int main(void)
{
queue job_queue = new_job_queue();
running = 1;
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = &handler;
sigaction(SIGINT, &sa, NULL);
/* create a bunch of threads */
init_threads(&job_queue);
while(running) {
/* do stuff */
}
cleanup();
return (0);
}
threads.c
extern sig_atomic_t running;
pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER;
sem_t queue_count;
void init_threads(queue *q)
{
int numthreads = 12; /* say */
sem_init (&queue_count, 0, 0);
pthread_t worker_threads[numthreads];
int i;
for(i=0;i<numthreads;i++)
pthread_create(&worker_threads[i], NULL, &thread_function, q);
}
void * thread_function(void *args)
{
pthread_detatch(pthread_self());
queue *q = (queue *)args;
while(running) {
job *j = NULL;
sem_wait(&queue_count);
pthread_mutex_lock(&queue_mutex);
j = first_job_in_queue(q);
pthread_mutex_unlock(&queue_mutex);
if(j) {
/*do something*/
}
}
return (NULL);
}
Мне немного повезло с этим. Поскольку вы не уверены, какая нить получает сигнал, я подумал, что это хороший путь. Но у меня есть проблема, где sem_wait()
в threads.c висит, что ожидается, но не желательно. Цикл while(running)
в threads.c кажется избыточным. Должен ли я сделать pthread_kill()
для всех потоков из основного? Есть ли очевидные проблемы с приведенным выше скелетным кодом? Есть ли лучший / более простой способ сделать это?
Спасибо.