【问题标题】:Multi-Threading in C++ throws thread constructor failed: Resource temporarily unavailableC++ 中的多线程抛出线程构造函数失败:资源暂时不可用
【发布时间】:2014-11-01 18:01:36
【问题描述】:

编辑:

我正在以矩阵乘法为例学习多线程,并创建了这个程序:

#include <iostream>
#include <vector>
#include <thread>
#include <functional>

using namespace std;

int N = 50;
void do_multiply_for_row(const vector<vector<int> >& matrix, int i, int N, vector<int>& answer) {
    for (int j = 0; j < N; j++) {
        answer[j] = 0;
        for (int k = 0; k < N; k++) {
            answer[j] += matrix[i][k] * matrix[k][j];
        }
    }
    cout << "Done " << i <<  endl;
}

int main() {
    vector<vector<int> > matrix(N, vector<int> (N, 0));
    int x = 0;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            matrix[i][j] = x++;
        }
    }
    vector<vector<int> > result(N, vector<int> (N, 0));
    vector<std::thread> threads;
    for (int i = 0; i < N; i++) {
            threads.push_back(std::thread(std::bind(do_multiply_for_row, std::cref(matrix), i, N, std::ref(result[i]))));
    }
    for (int i = 0; i < threads.size(); i++) threads[i].join();
    for (int i = 0; i < N; i++) {
        for (int j =0; j < N; j++){
            cout << result[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

我最终会创建 50 个线程,但得到了 libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: thread constructor failed: Resource temporarily unavailable

我创建的线程数量是否有限制或我做错了什么?

【问题讨论】:

  • NVM,我是一个小丑,一次又一次地为同一行创建线程。
  • 您可以创建的线程数是有限制的,这最终取决于您的系统。
  • 没关系。我正在比较我的单线程矩阵乘法和多线程矩阵乘法的结果,单线程总是赢!
  • 对不同线程上的每一行进行计算不太可能提高性能。您必须分批划分行并在每个线程的多行上运行计算。假设您有 500 行和 4 个核心,您在每个核心上运行 125 行的计算。
  • std::thread(std::bind(args...)) 在语义上等同于std::thread(args...)。省略std::bind 并节省一些按键操作。

标签: c++ multithreading c++11


【解决方案1】:

线程实现取决于系统,线程数的限制也是如此。

您的错误消息显示:“resource_unavailable_try_again — 系统缺乏创建另一个线程所需的资源,或者系统对线程数的限制过程将被超越。” (标准 c++,30.3.1.2/8):

多线程效率有一个限制,即thread::hardware_concurrency()。该值是硬件支持的线程数的近似值(但如果没有线索,该函数可能会返回 0):

  • 您当然可以创建更多线程,但您的操作系统将不得不切换上下文以让它们运行(即暂停一些正在运行的线程以让等待的线程也有机会执行)。这意味着某些线程不会真正并发运行。

  • 1234563

这个观点有两个提示。首先,您可以在线程中插入this_thread::yield();,尤其是在它们有大量循环的情况下。如果所有硬件线程都忙,这为其他线程提供了调度的机会。其次,您可以考虑thread pools:创建固定数量的线程,每次完成计算时从队列中挑选任务。

【讨论】:

    猜你喜欢
    • 2014-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    • 2019-08-14
    相关资源
    最近更新 更多