线程池应该如何在 C 中实现

How should a thread pool be implemented in C?

本文关键字:实现 线程      更新时间:2023-10-16

我正在用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

几个月前我用过谷歌,你应该试试。

编辑:似乎你想要一个小组。 我能够通过对上述内容进行一些小改动来创建,以便工人不执行工作,而只是加入线程。