Note that there are some explanatory texts on larger screens.

plurals
  1. POProblems in destroying threads in thread pool
    primarykey
    data
    text
    <p>I implements a thread pools using C programming language in Linux enviromnent.There is a blocking task queue, we can put task in the task queue, the threads in the thread pool get task from the task queue, and if the task queue is empty, it wound block waiting for a condition signal saying that the task queue is not empty. The function that the thread in thread pool run is:</p> <pre><code> static void *do_worker(void *arg) { printf("new thread %d\n", pthread_self()); ThreadPool *pool = (ThreadPool *)arg; while (1) { printf("thread %d try to get new task\n", pthread_self()); Task task; //printf("before get_task\n"); task = get_task(&amp;pool-&gt;task_queue); printf("thread %d get_task\n", pthread_self()); if (task.ftn == NULL ) { break; } task.ftn(task.arg); //printf("finish new task\n"); //printf("I'm thread %d\n", pthread_self()); } printf("thread %d exit\n", pthread_self()); pthread_exit(NULL); } </code></pre> <p>it seems fine when i add normal task to the queue,but when i try to destroy the thread pool, using poison task, just like this:</p> <pre><code> void destroy_threadpool(ThreadPool *pool) { int i; /* put poison to let the threads exit */ for (i = 0; i &lt; pool-&gt;t_cnt; i++) { Task null_task; null_task.ftn = NULL; null_task.arg = NULL; printf("insert poison task\n"); insert_task(pool, null_task); } for (i = 0; i &lt; pool-&gt;t_cnt; i++) { pthread_join(pool-&gt;tids[i], NULL); } } </code></pre> <p>it doesn't work. And when i test this implemention,i have first made the threads in the thread pool blocked in waiting the not empty condition, then i invoke the destroy_threadpool function. However, some threads can exit, but some can't,still blocked in waiting the condition,which results in the main thread blocking in pthread_join. what can be the probelm?</p> <p>The code of get_task and put_task are:</p> <pre><code> Task get_task(TaskQueue *queue) { Task task; pthread_mutex_lock(&amp;queue-&gt;mutex); while (queue-&gt;front == queue-&gt;back) { printf("thread %d blocks!\n", pthread_self()); pthread_cond_wait(&amp;queue-&gt;no_empty, &amp;queue-&gt;mutex); } /* get the front task in the queue */ memcpy(&amp;task, &amp;queue-&gt;tasks[queue-&gt;front], sizeof(Task)); if (++queue-&gt;front == MAXTASK) { queue-&gt;front = 0; } pthread_cond_signal(&amp;queue-&gt;no_full); pthread_mutex_unlock(&amp;queue-&gt;mutex); return task; } void put_task(TaskQueue *queue, Task task) { pthread_mutex_lock(&amp;queue-&gt;mutex); while (((queue-&gt;back + 1) == queue-&gt;front) || (queue-&gt;back - queue-&gt;front == MAXTASK - 1)) { pthread_cond_wait(&amp;queue-&gt;no_full, &amp;queue-&gt;mutex); } memcpy(&amp;queue-&gt;tasks[queue-&gt;back], &amp;task, sizeof(task)); if (++queue-&gt;back == MAXTASK) { queue-&gt;back = 0; } pthread_cond_signal(&amp;queue-&gt;no_empty); pthread_mutex_unlock(&amp;queue-&gt;mutex); } </code></pre> <p>The definition of ThreadPool and TaskQueue are:</p> <pre><code> typedef struct { void *(*ftn)(void *arg); void *arg; } Task; typedef struct { Task tasks[MAXTASK]; int front; int back; pthread_mutex_t mutex; pthread_cond_t no_empty; pthread_cond_t no_full; } TaskQueue; typedef struct { pthread_t tids[MAXTHREAD]; int t_cnt; TaskQueue task_queue; } ThreadPool; </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload