编辑:
我正在学习使用Matrix Multiplication的多线程作为示例,我创建了这个程序:
#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
我创建的线程数量是否有限制,或者我做错了什么?
答案 0 :(得分:3)
线程实现是系统相关的,线程数量的限制也是如此。
您的错误消息显示:&#34; resource_unavailable_try_again - 系统缺少创建另一个线程所需的资源,或系统强加的限制将超过进程中的线程数。&#34; (标准c ++,30.3.1.2 / 8):
对于Linux,total number of threads on the system有一个限制。
对于Windows,没有predefined limit to number of threads,但其内存消耗(尤其是其堆栈)将事实上将其限制为几千个活动线程。在Mark Russinovitch's blog上,您可以找到一个工具来测试您自己系统的限制。
多线程效率有一个限制,即thread::hardware_concurrency()
。此值是硬件支持的线程数的近似值(但如果没有线索,则函数可能返回0):
您当然可以创建更多线程,但您的操作系统必须切换上下文才能让它们运行(即保持一些正在运行的线程以便让等待的线程也能执行)。这意味着某些线程不会真正同时运行。
如果您运行的线程数少于thread::hardware_concurrency()
,则无法确定是否真正使用了并发:除您之外的其他进程也可能使用某些可用容量。
从这个角度来看两个提示。首先,您可以在线程中插入this_thread::yield();
,尤其是在它们有重环的情况下。如果所有硬件线程都忙,则可以安排其他线程进行调度。其次,您可以考虑thread pools:创建固定数量的线程,每次完成计算时从队列中选择任务。