2012-04-12 6 views
1
gcc (GCC) 4.6.3 
valgrind-3.6.1 

Я создал приложение, которое отправляет и получает сообщения в 2 разных потоках для отправки и получения. Использование pthreads, переменных условий и мьютексов для блокировок.Отмена или убийство pthread

Однако отправитель отправляет сообщения, а затем сигнализирует приемнику о его получении и обработке. Он делает это в цикле while.

Однако проблема возникает, если я хочу выйти из приложения с помощью ctrl-c и обработать interupt. Если сообщения не отправляются, приемник застревает в цикле while, ожидающем приема.

Главный поток вызовет соединение и блок, ожидающие окончания приемника. Но это не так, как ожидалось на pthread_cond_wait.

Я думал об использовании pthread_cancel или pthread_kill. Но я не люблю это делать, поскольку он не позволяет потоку нормально выходить.

Большое спасибо за любые предложения.

Основная функция

void main(void) 
    { 
     /* Do some stuff here */ 

    /* Start thread that will send a message */ 
    if(pthread_create(&thread_recv_id, &thread_attr, thread_recv_fd, NULL) == -1) { 
     fprintf(stderr, "Failed to create thread, reason [ %s ]", 
      strerror(errno)); 
      break; 
     } 
     printf("Start listening for receiving data'\n"); 

     /* Start thread to receive messages */ 
     if(pthread_create(&thread_send_id, &thread_attr, thread_send_fd, NULL) == -1) { 
      fprintf(stderr, "Failed to create thread for receiving, reason [ %s ]", 
        strerror(errno)); 
      break; 
     } 

    /* Clean up threading properties */ 
    pthread_join(thread_send_id, NULL); 
    pthread_join(thread_recv_id, NULL); <---- blocking here waiting for the recv thread to finish 

    pthread_mutex_destroy(&mutex_queue); 
    pthread_cond_destroy(&cond_queue); 

    return 0; 
} 

отправителем нить

void *thread_send_fd() 
{ 
     pthread_mutex_lock(&mutex_queue); 
     if(send_fd((int)fd) == FALSE) { 
      /* Just continue to send another item */ 
      continue; 
     } 
     /* Signal the waiting thread to remove the item that has been sent */ 
     pthread_cond_signal(&cond_queue); 

     pthread_mutex_unlock(&mutex_queue); 
} 

приемник нить

void *thread_recv_fd() 
{ 
    while(is_receiving()) { 
     pthread_mutex_lock(&mutex_queue); 

     /* Wait for an item to be sent on the queue */ 
     pthread_cond_wait(&cond_queue, &mutex_queue); <---- waiting here 

     queue_remove(); 
     pthread_mutex_unlock(&mutex_queue); 
    } 

    pthread_exit(NULL); 
} 
+1

Если вы не присоединяетесь к потоку recv, он не будет блокировать выход из основного потока, и ОС остановит оба.Если поток recv не содержит ресурсов между процессами и т. П., Просто дайте ОС остановить его. –

ответ

9

Вы основная по имеют 3 варианта:

  1. Использование pthread_cancel. Это прервет вызов pthread_cond_wait, а затем выйдет из потока, вызвав обработчики отмены, зарегистрированные с pthread_cleanup_push по пути вверх.

  2. Использовать pthread_kill до Отправить сообщение по этому вопросу. Это не «убивает» поток, он просто посылает сигнал. В этом случае вы должны зарегистрировать обработчик сигнала в этом потоке для сигнала, который вы используете, и этот обработчик сигнала должен что-то сделать, чтобы сообщить потоку выйти. Это не особенно лучше, чем третий вариант, так как обработчик сигнала все равно должен что-то сделать, чтобы завершить цикл цикла pthread_cond_wait.

  3. Включите функцию ручного прерывания в поток, который знает, установить флаг и сигнализировать переменную условия. Затем цикл вокруг pthread_cond_wait должен проверить флаг и выйти из потока, если флаг установлен.

Я бы порекомендовал (1) или (3). Использование pthread_cancel является наиболее общим, но требует тщательной обработки в потоке, чтобы обеспечить подходящие вызовы pthread_cleanup_push для очистки всех ресурсов, выделяемых потоком, разблокировки всех мьютексов и т. Д. Написание функции прерывания вручную потенциально больше работает, но может быть наиболее легко адаптировано к вашему приложению.

+4

4. Прекратите использовать соединение, когда это вам не нужно. –

Смежные вопросы