2013-12-16 3 views
4

У меня довольно простой пул потоков, и у меня есть вопрос о завершении нити.pthread exit из потока в пуле потоков

это мой рабочий фрагмент кода:

static void* threadpool_worker(void* pool_instance) 
{ 
    int rc; 
    struct threadpool* pool = (struct threadpool*)pool_instance; 
    struct threadpool_task *task; 

    for(;;) 
    { 
     pthread_mutex_lock(&(pool->task_queue_mutex)); 

     while(pool->headp->tqh_first == NULL) 
     { 
      rc = pthread_cond_wait(&(pool->task_queue_cond), &(pool->task_queue_mutex)); 
     } 

     task = pool->headp->tqh_first; 
     TAILQ_REMOVE(pool->headp, pool->headp->tqh_first, entries); 

     pthread_mutex_unlock(&(pool->task_queue_mutex)); 
     task->routine_cb(task->data); 
    } 

} 

так работы выполняются на этой линии Задачи-> routine_cb (Задачи-> данные);

и для того, чтобы завершить работу над рабочим темы я звоню threadpool_enqueue_task

следующим образом:

for(i=0 ; i < pool->num_of_workers ; ++i) 
{ 
    threadpool_enqueue_task(pool, pthread_exit, NULL); 
} 

ожидал, что pthread_exit будет называться здесь Задачи-> routine_cb (Задачи-> данные) , но она не работает таким образом, я не вижу никакой явной ошибки, просто утечка памяти в Valgrind

, но когда я изменить код уборщица так:

if(task->routine_cb == pthread_exit) 
    { 
     pthread_exit(0); 
    } 
    task->routine_cb(task->data); 

все кончается отлично. , так что мой вопрос в том, есть ли возможность остановить работника, просто заставить его выполнить pthread_exit каким-то образом, не меняя рабочий код.

Edit: задача пула потоков объявлен следующим образом:

struct threadpool_task 
{ 
    void (*routine_cb)(void*); 
    void *data; 
    TAILQ_ENTRY(threadpool_task) entries;   /* List. */ 
} 

согласно моему understanig не должно быть никаких проблем, чтобы получить адрес pthread_exit в routine_cb, который заявил:

extern void pthread_exit (void *__retval) __attribute__ ((__noreturn__)); 
+0

Полезно? http://stackoverflow.com/questions/2084830/kill-thread-in-pthread-library –

+0

они предлагают на самом деле то, что я пытаюсь избежать, id не хочет использовать pthread_cancel из причин, упомянутых в этом сообщении: pthread_cancel (thr) Однако это не рекомендуемая практика программирования! Лучше использовать механизм связи между потоками, такой как семафоры или сообщения, для связи с потоком, чтобы он прекратил выполнение. – Dabo

+0

Какой OS/компилятор вы используете? –

ответ

0

Я нашел причиной утечки. Конечно, это была моя вина. Я переписал вызов работу следующим образом:

void (*routine)(void*) = task->routine_cb; 
    void* data = task->data; 
    free(task); 
    routine(data); 

вместо:

task->routine_cb(task->data); 
    free(task); 

и там больше не было утечек, и потоки остановились, как я ожидал. Спасибо всем, кто пытался помочь.

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