0

I'm new to multithread programming in C++, and am trying to use thread pools in my code. My code is pretty simple.

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

const int SIZE = 100000;

void foo() {
    std::cout << "foo" << std::endl;
}

int main() {
    std::vector<std::thread> myThreads;

    for (int i = 0; i < SIZE; i++) {
        myThreads.push_back(std::thread(foo));
    }

    for (auto& myThread : myThreads) {
        myThread.join();
    }

    return 0;
}

When I run this code from Visual Studio 15 on Windows 10, no problem. It works. My issue is when I run it on my Raspberry Pi 3 I get an error that says:

terminate called after throwing an instance of 'std::system_error'
  what(): Resource temporarily unavailable

Now I assume that what's happening is that the Pi's weak CPU simply can't handle such a large quantity of threads at once. When I change the SIZE down to 100 or 200, the code executes fine.

So why is it that this many threads causes the program to fail? Do the threads not wait to be executed or what is the problem?

John Seed
  • 357
  • 1
  • 7
  • 18
  • Possible duplicate of [Multi-Threading in C++ throws thread constructor failed: Resource temporarily unavailable](http://stackoverflow.com/questions/26691340/multi-threading-in-c-throws-thread-constructor-failed-resource-temporarily-un) – Swift - Friday Pie Jan 26 '17 at 06:12
  • 2
    You are misinterpreting the goal of a thread pool. A pool is a small number of threads, often only one per processor core available, available to do work. A job is assigned to the pool, and one of the threads will be assigned the job. There are a number of job-allocating schemes to spread the work around so that no one thread is over taxed while others lie idle. – user4581301 Jan 26 '17 at 06:12
  • 2
    The whole point of a thread pool is to allow you to use a small number of threads, not much larger than the number of cores you have. Have a look at [this](http://stackoverflow.com/a/29742586/721269) simple thread pool that I wrote. – David Schwartz Jan 26 '17 at 06:13
  • I was going to answer this with a simple thread pool example to help you understand the difference between a [thread pool](https://en.wikipedia.org/wiki/Thread_pool) and a list of threads, but @DavidSchwartz [already](http://stackoverflow.com/questions/26516683/reusing-thread-in-loop-c/29742586#29742586) did so. Additionally, you're trying to tell the kernel to create and manage 100,000 threads in a tight loop; this might appear to work fine on your Window machine (which probably has an Intel CPU) but chokes on your ARM based Pi because of the differences in architecture and thread management. – txtechhelp Jan 26 '17 at 08:17
  • Smells like an OutOfMemory exception to me. – Ignacio Soler Garcia Jan 26 '17 at 08:40

3 Answers3

0

Threads take up space. They require memory for a control structure and to store context. In addition, they require a system handle in some environments. System handles are limited. You are probably taxing the ability of the OS on your Raspberry Pi.

Mikel F
  • 3,567
  • 1
  • 21
  • 33
0

Normally folks restrict the number of thread to something like std::thread::hardware_concurrency() to limit it to the number of cores you have on your hardware.

You can create more threads, of course. But not all of them will be able to run, and each thread has its own allocated stack frame. -- So at some point you'll run out of virtual memory on your hardware, a Raspberry Pi.

(It is also possible to fit more in by adjusting your stack size... Just be careful.)

geipel
  • 395
  • 1
  • 3
  • 9
0

There's no sense to create more thread at once than a number of cores that your system can provide, they just would compete for the CPU time and slow down your application.

As already mentioned, you can get it using std::thread::hardware_concurrency(), but not sure about Raspberry, on some platforms it just returns 0.

If you have a lot of jobs (much more than CPU cores) you should use some thread-pool implementation, that put your jobs into the queue and execute not more than N (that is usually std::thread::hardware_concurrency()) in a time

You can find plenty of simple thread pool implementations on GitHub, for example

  • There are lots of reasons to create more threads than the number of cores that your system can provide. The most obvious one is to allow you to keep all of your cores busy even if one of your threads is not blocked on I/O, say due to a page fault. – David Schwartz Jan 27 '17 at 00:43