I have a queue of jobs and I want to make a pool of 4 threads where I can throw my jobs at. What I am stuck at is in how to make the threads and keep them suspended while there is no work.
我有一个任务队列,我想创建一个包含4个线程的池,我可以在其中放置我的任务。我所关注的是如何在没有工作的情况下使线程保持挂起。
JOB QUEUE | job1 | job2 | job3 | job4 | ..
THREAD POOL | thread1 | thread2 | thread3 | thread4 |
To create the threads I have currently at the initialisation point:
创建我目前在初始化点的线程:
for (t=0; t<num_of_threads; t++){
pthread_create(&(threads[t]), NULL, doSth2, NULL);
}
Where num_of_threads=4 and doSth2 is a function with nothing inside. So once I have created the 4 threads and they are done with doSth2, how can I give them new work to do, without killing them?
num_of_threads=4和doSth2是一个内部没有任何内容的函数。因此,一旦我创建了这4个线程,并且它们已经完成了doSth2,我如何能给它们新的工作,而不杀死它们呢?
2 个解决方案
#1
17
The key to a thread pool is a queue. Here are modified functions for a thread pool I have developed.
线程池的关键是队列。下面是我开发的线程池的修改函数。
Put element in queue
void queue_add(queue q, void *value)
{
pthread_mutex_lock(&q->mtx);
/* Add element normally. */
pthread_mutex_unlock(&q->mtx);
/* Signal waiting threads. */
pthread_cond_signal(&q->cond);
}
Get element from queue
void queue_get(queue q, void **val_r)
{
pthread_mutex_lock(&q->mtx);
/* Wait for element to become available. */
while (empty(q))
rc = pthread_cond_wait(&q->cond, &q->mtx);
/* We have an element. Pop it normally and return it in val_r. */
pthread_mutex_unlock(&q->mtx);
}
#2
3
As an alternate riff on cnicutar's answer you can just use POSIX message queues which will take care of the synchronization concerns in the kernel. There will be some small overhead for the system calls which may or may not be a concern. It is pretty minimal as the kernel is doing everything you would have to do manually anyway.
作为对cnicutar答案的另一个重复,您可以使用POSIX消息队列来处理内核中的同步问题。系统调用的开销将会很小,这可能是一个问题,也可能不是。这是非常小的,因为内核正在做任何你不得不手工做的事情。
The consumer threads can just block on mq_receive
and if you create a special type of queue message it makes it easy to tell the threads when to shut down.
使用者线程可以在mq_receive上阻塞,如果您创建一种特殊类型的队列消息,就可以很容易地告诉线程何时关闭。
#1
17
The key to a thread pool is a queue. Here are modified functions for a thread pool I have developed.
线程池的关键是队列。下面是我开发的线程池的修改函数。
Put element in queue
void queue_add(queue q, void *value)
{
pthread_mutex_lock(&q->mtx);
/* Add element normally. */
pthread_mutex_unlock(&q->mtx);
/* Signal waiting threads. */
pthread_cond_signal(&q->cond);
}
Get element from queue
void queue_get(queue q, void **val_r)
{
pthread_mutex_lock(&q->mtx);
/* Wait for element to become available. */
while (empty(q))
rc = pthread_cond_wait(&q->cond, &q->mtx);
/* We have an element. Pop it normally and return it in val_r. */
pthread_mutex_unlock(&q->mtx);
}
#2
3
As an alternate riff on cnicutar's answer you can just use POSIX message queues which will take care of the synchronization concerns in the kernel. There will be some small overhead for the system calls which may or may not be a concern. It is pretty minimal as the kernel is doing everything you would have to do manually anyway.
作为对cnicutar答案的另一个重复,您可以使用POSIX消息队列来处理内核中的同步问题。系统调用的开销将会很小,这可能是一个问题,也可能不是。这是非常小的,因为内核正在做任何你不得不手工做的事情。
The consumer threads can just block on mq_receive
and if you create a special type of queue message it makes it easy to tell the threads when to shut down.
使用者线程可以在mq_receive上阻塞,如果您创建一种特殊类型的队列消息,就可以很容易地告诉线程何时关闭。