Reputation: 6350
Edited:
I'm learning multi-threading with Matrix Multiplication as an example and I have created this program:
#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;
}
I'll end up creating 50 threads but got libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: thread constructor failed: Resource temporarily unavailable
Is there a limit on number of threads i create or i'm doing something wrong?
Upvotes: 2
Views: 13345
Reputation: 73617
The thread implementation is system dependent, and so are the limits to the number of threads.
Your error message shows that: "resource_unavailable_try_again — the system lacked the necessary resources to create another thread, or the system-imposed limit on the number of threads in a process would be exceeded." (Standard c++, 30.3.1.2/8):
For Linux, there is a limit on the total number of threads on the system.
For Windows, there is no predefined limit to number of threads, but its memory consumption, in perticular for its stack, will de facto limit it to a couple of thousands of active threads. On Mark Russinovitch's blog you can find a tool to test the limits on your own system.
There is a limit to multithreading efficiency, which is thread::hardware_concurrency()
. This value is an approximation of the number of threads supported by hardware (but the function might return 0 if it ha no clue):
You may of course create more threads, but your operating system will have to switch context to let them run (i.e. put on hold some running threads to give waiting ones opportunity to execute as well). This means that some of the threads will not run really concurrently.
If you run less threads than thread::hardware_concurrency()
, you can't be sure either that concurrency is really used: other processes than yours may also use some of the available capacity.
Two hints in this perspective. First you could insert a this_thread::yield();
in threads, especially if they have heavy loops. THis gives opportunity to other threads to be scheduled in, if all the hardware threads are busy. Second, you could consider thread pools: creating a fixed number of threads, that pick tasks from a queue each time they have finished a calculation.
Upvotes: 6