我用C ++编程,但我只使用pthread.h,没有boost或C ++ 11线程。
所以我尝试使用线程,但基于我之前的一个问题(link),这似乎不可行,因为线程在完成任务后立即终止,而且其中一个使用线程池实现的普遍原因是通过将这些线程重用于多个任务来减少线程创建开销。
这是在C中实现这个以使用fork()的唯一其他方法,并从主进程到子进程创建管道?或者有没有办法在线程和父母之间建立一条我不知道的管道?
非常感谢提前!
答案 0 :(得分:6)
是的,您可以在线程之间创建thread-safe queue。然后,池中的线程将坐在循环中,从队列中检索项目,执行它需要的任何内容,然后返回并获取另一个项目。
这在C ++中通常更简单/更简单,因为它更容易在某些界面上达成一致(例如,重载operator()
来执行任务的代码),但在基本层面上你可以做C中的所有相同的东西(例如,你放入队列的每个task
结构将包含一个指向函数的指针,以执行该任务的工作。)
在您的情况下,由于您使用的是C ++,因此使用operator()
的重载来完成工作可能更容易。 task
结构的其余部分(或您选择的任何结构)将包含所需的任何数据等。
答案 1 :(得分:3)
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。
答案 2 :(得分:2)
'似乎不可行,因为线程在完成任务'what ??
后立即终止for(;;){
Task *myTask=theCommonProducerConsumerQueue->pop();
myTask->run();
}
..永远不会返回任何东西,实际上永远不会回来。
答案 3 :(得分:2)
您可能会发现查看the source code for libdispatch很有帮助,{{3}}是Apple Grand Central Dispatch的基础并使用线程池。
答案 4 :(得分:1)
我建议使用英特尔的Threaded Building Blocks来完成工作队列/线程池之类的任务。使用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);
}
答案 5 :(得分:-1)
我几个月前使用谷歌,你应该尝试一下。
编辑:似乎你可能想要一个团队。我能够创建一个对上面做了一些小改动,以便工人不进行工作,但只是加入了线程。