C++ 重用调用同一函数的线程 vector

标签 c++ multithreading c++14 threadpool stdthread

我想重用一个线程 vector ,这些线程使用不同的参数多次调用同一函数。没有写入(原子参数除外),因此不需要互斥体。为了描述这个想法,我创建了一个并行代码的基本示例,用于查找 vector 的最大值。显然有更好的方法来找到 vector 的最大值,但为了解释并避免深入了解我正在编写的实际代码的更多细节,我将使用这个愚蠢的示例。

代码通过调用函数pFind来查找 vector 的最大数量,该函数检查 vector 是否包含数字k(k是初始化为上限)。如果是,则执行停止,否则k减一并重复该过程。

下面的代码生成一个线程 vector ,并行化 vector 中k的搜索。问题是,对于 k 的每个值,每次连接新线程时都会重新生成线程 vector 。 生成线程 vector 并每次连接它们都会带来我想避免的开销。

我想知道是否有一种方法只生成一次线程 vector (池)并将其重用于新的执行。任何其他加速技巧将不胜感激。

void pFind(
    vector<int>& a,
    int n,
    std::atomic<bool>& flag,
    int k,
    int numTh,
    int val
    ) {
    int i = k;

    while (i < n) {
        if (a[i] == val) {
            flag = true;
            break;
        } else 
            i += numTh;
    }
}

int main() {   
    std::atomic<bool> flag;
    flag = false;
    int numTh = 8;
    int val = 1000;
    int pos = 0;

    while (!flag) {
        vector<thread>threads;
        for (int i = 0; i < numTh; i++){ 
            thread th(&pFind, std::ref(a), size, std::ref(flag), i, numTh, val);
            threads.push_back(std::move(th));
        }
        for (thread& th : threads) 
            th.join();

        if (flag) 
           break;

        val--;

   }
   cout << val << "\n";
   return 0;
}

最佳答案

构造后无法为 std::thread 分配不同的执行函数(闭包)。对于所有线程抽象来说,这通常都是正确的,尽管实现通常会尝试在内部内存或缓存较低级别的抽象,以使线程快速 fork 和连接,因此仅构造新线程是可行的。系统编程界有一个争论,即创建一个新线程是否应该非常轻量级,或者客户端是否应该被编写为不那么频繁地 fork 线程。 (考虑到这种情况已经持续了很长一段时间,很明显涉及到很多权衡。)

还有很多其他抽象试图做你真正想做的事情。它们的名称包括“线程池”、“任务执行器”(或只是“执行器”)和“futures”。所有这些都倾向于通过创建一些线程集(通常与系统中的硬件核心数量相关)来映射到线程,然后让每个线程循环并查找请求。

正如评论所指出的,您自己执行此操作的主要方法是让线程具有顶级循环,该循环接受执行请求,处理它们,然后发布结果。为此,您需要使用其他同步方法,例如互斥体和条件变量。如果有很多请求并且请求不是非常大,那么通常以这种方式执行操作会更快。

尽管标准 C++ 并发支持是一件好事,但对于现实世界的高性能工作来说,它也相当缺乏。类似于 Intel's TBB更像是一种工业强度的解决方案。

关于C++ 重用调用同一函数的线程 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47171107/

相关文章:

c++ - 在编译时截断字符串

c++ - 在 C++ 中将 std::minus 专门用于用户定义类型是否合法?

c++ - 返回 shared_ptr 中的对象时 RVO 会工作吗?

multithreading - Haskell 中的随机数生成器是线程安全的吗?

java - Java线程同步问题

ios - 串行队列比同步块(synchronized block)更快吗?

c++ - 为参数顺序不同的模板类创建比较特征

c++ - 无法推导成员函数包装器的返回类型

c++ - FormatDateTime-整数算术溢出C++

c++ - 如何在 C++ 类中接收来自 Objective-C 的 NSNotifications?