线程池应该如何在 C 中实现
How should a thread pool be implemented in C?
我正在用C++编程,但我只使用 pthread.h,没有 boost 或 C++11 线程。
所以我正在尝试使用线程,但根据我之前的问题之一(链接),这似乎不可行,因为线程在其任务完成后立即终止,并且使用线程池实现的更普遍原因之一是通过重用这些线程来减少线程创建开销多个任务。
那么在 C 中实现这一点的唯一其他方法是使用 fork() 并创建从主进程到子进程的管道吗?或者有没有办法在线程和我不知道的父线程之间设置管道?
提前非常感谢!
是的,您可以在线程之间创建线程安全队列。然后,池中的线程将处于循环中,从队列中检索一个项目,执行它需要的任何内容,然后返回并获取另一个项目。
这在C++中通常更容易/更简单一些,因为在某些接口上达成一致会更容易一些(例如,重载operator()
执行任务的代码),但在基本层面上,你可以在 C 中做所有相同的事情(例如,你放入队列中的每个task
结构都将包含一个指向函数的指针来执行该任务的工作)。
在您的情况下,由于您使用的是C++,因此使用重载operator()
来完成工作可能更容易。task
结构的其余部分(或你选择调用它的任何内容)将包含所需的任何数据,等等。
根据 POSIX 标准:
int pthread_create(pthread_t *restrict thread,
const pthread_attr_t *restrict attr,
void *(*start_routine)(void*), void *restrict arg);
(...线程是执行
start_routine
创建的,arg
作为其唯一参数。
因此,您应该使用此函数创建一堆线程,并让它们都执行类似
void *consumer(void *arg)
{
WorkQueue *queue = static_cast<WorkQueue *>(arg);
for (task in queue) {
if (task == STOP_WORKING)
break;
do work;
}
return WHATEVER;
}
(在输入结束时,将 n 个STOP_WORKING
项推送到队列,其中 n 是线程数。
请注意,pthreads 是一个非常低级的 API,它提供很少的类型安全性(所有数据都作为void
指针传递)。如果您尝试并行化 CPU 密集型任务,则可能需要查看 OpenMP
似乎不可行,因为线程在完成其任务后立即终止"什么??
for(;;){
Task *myTask=theCommonProducerConsumerQueue->pop();
myTask->run();
}
.. 永遠不回歸任何東西,事實上,永遠不會回歸。
您可能会发现查看libdispatch的源代码很有帮助,这是Apple的Grand Central Dispatch的基础,并使用线程池。
我建议使用英特尔的线程构建模块来完成类似工作队列/线程池的任务。一个使用 TBB 3.0 的相当人为的例子:
class PoorExampleTask : public tbb::task {
PoorExampleTask(int foo, tbb::concurrent_queue<float>& results)
: _bar(foo), _results(results)
{ }
tbb::task* execute() {
_results.push(pow(2.0, foo));
return NULL;
}
private:
int _bar;
tbb::concurrent_queue<float>& _results;
}
稍后使用如下:
tbb::concurrent_queue<float> powers;
for (int ww = 0; ww < LotsOfWork; ++ww) {
PoorExampleTask* tt
= new (tbb::task::allocate_root()) PoorExampleTask(ww, powers);
tbb::task::enqueue(*tt);
}
http://people.clarkson.edu/~jmatthew/cs644.archive/cs644.fa2001/proj/locksmith/code/ExampleTest/threadpool.c
几个月前我用过谷歌,你应该试试。
编辑:似乎你想要一个小组。 我能够通过对上述内容进行一些小改动来创建,以便工人不执行工作,而只是加入线程。
- 在c++队列中使用pop和visit实现线程安全
- 我是否需要在 OpenSSL 1.1.0+ 中使用加密锁定函数来实现线程安全?
- 如何使用自然外观的语法实现线程安全容器
- 如何实现线程以同步对向量向量进行排序
- 使用pthreads实现线程池
- 以下单例实现线程是否安全?
- 实现线程锁时是否真的需要原子性
- C++,当每个工作线程都必须执行几个不同的任务时,如何为任务实现线程池
- 在 C++ 中使用 pthreads 实现线程池
- 此同步对象实现线程是否安全
- 如何在 C++03 中实现线程安全的局部静态变量
- C++用线程间通信实现线程
- 为什么Boost库在实现线程屏障时使用m_generation变量
- 以下是单例实现线程安全的
- 在三层架构中实现线程:无法打开数据库
- setjmp和longjump来实现线程
- 使用C++实现线程安全并通过引用
- 如何实现线程安全的LRU缓存回收
- 如何在c++中实现线程池?
- std::互斥量是否足以实现线程间的数据同步?