如何使用带有 pthreads 的线程池?
Posted
技术标签:
【中文标题】如何使用带有 pthreads 的线程池?【英文标题】:How to utilize a thread pool with pthreads? 【发布时间】:2011-10-20 17:38:22 【问题描述】:我有一个作业队列,我想创建一个由四个线程组成的池,我可以在其中投入我的作业。我坚持的是如何制作线程并在没有工作的情况下让它们暂停。
JOB QUEUE | job1 | job2 | job3 | job4 | ..
THREAD POOL | thread1 | thread2 | thread3 | thread4 |
在初始化点创建我当前拥有的线程:
for (t=0; t<num_of_threads; t++)
pthread_create(&(threads[t]), NULL, doSth2, NULL);
其中num_of_threads=4
和doSth2
是一个内部没有任何内容的函数。
因此,一旦我创建了 4 个线程并使用 doSth2
完成了它们,我怎样才能在不杀死它们的情况下给它们新的工作?
【问题讨论】:
【参考方案1】:线程池的关键是队列。这是我开发的线程池的修改函数。
将元素放入队列
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);
从队列中获取元素
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);
【讨论】:
谢谢。我现在明白了。池中的每个线程都应该从队列中串行读取。但是,如果队列为空,您如何暂停线程以便它们不会占用 CPU? @Pithikospthread_cond_wait
阻止,直到有人 (queue_add
) 发出信号 cond
。
抱歉这么晚才打开,但是如果 queue_get 锁定了 mtx 然后循环,如果 mtx 被锁定,你怎么能添加一个项目?锁不应该在循环之后(例如循环 -> 锁定 -> 弹出 -> 解锁)吗?
不久前我知道-回答@AlexandreGomes-pthread_cond_wait(来自人[linux.die.net/man/3/pthread_cond_wait])在等待时解锁互斥锁,供其他线程使用,并返回再次锁定它。因此,互斥体作为参数传递。【参考方案2】:
作为 cnicutar 答案的替代 riff,您可以使用 POSIX message queues 来处理内核中的同步问题。系统调用会有一些小的开销,这可能是也可能不是问题。它非常小,因为内核正在执行您必须手动执行的所有操作。
消费者线程可以在mq_receive
上阻塞,如果您创建一种特殊类型的队列消息,它可以很容易地告诉线程何时关闭。
【讨论】:
以上是关于如何使用带有 pthreads 的线程池?的主要内容,如果未能解决你的问题,请参考以下文章