how to reuse a thread multiple times in C?
Threads do not normally run to completion; rather they wait in an executive loop for some trigger event such as arrival of a message or semaphore. The pattern of a trpical thred function is:
void* func( void* arg )
{
// Thread initialisation
while( !terminated )
{
// Block waiting
...
// Do stuff (handle event/message for example)
...
}
// Clean-up
...
}
The signature of a thread function depends on the threading library/OS; the above is normal for pthreads for example. Also a thread may run indefinitely with a while(1)
or for(;;)
loop. The exact termination mechanism (i.e. the terminate
in my example is up to you; it is not required.
Thread-loops are often implementations of state-machines.
You can of course have a run-to-completion thread, but in that case you have to create a new thread fro every event - it is rather inefficient to to that.
The blocking call could be as simple as a sleep()
call for periodic tasks. It is possible to block at multiple places throughout a task, but to do so makes the design more complex to design and debug, and a state-machine pattern is normally a better solution.
Multithreading Reuse with Objects in While loop
Okay, I think this is your first problem.
std::thread threads[N_THREADS]; // array of threads
This will construct 10 threads, not SPACE for 10 threads. I wasn't absolutely positive, so I tested this way:
#include <iostream>
using namespace std;
class Foo {
public:
Foo() { cout << "Foo constructor.\n"; }
};
int main(int, char **) {
cout << "Allocate array.\n";
Foo array[10];
cout << "Loop.\n";
for (int i = 0; i < 10; ++i) {
array[i] = Foo();
}
cout << "Done.\n";
}
This displayed the output from my first prompt, then 10 "Foo constructor" messages, then my second "Loop" prompt, then 10 more "Foo constructor" messages.
I think you probably need to make that an array of thread pointers, and then use new, like this:
std::thread * thread[N_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
threads[i] = new std::thread(std::bind(&Population::populationMove, &pop, (i * NumberOfPlayers / NUM_THREADS)));
}
Next, thread.join is a method:
for (int i = 0; i < NUM_THREADS; i++) {
if(threads[i].joinable())
threads[i].join();
//std::cerr << "In Thread " << i << "\n";
}
You are missing () in two places in that code.
In C++, how can I reuse a standard thread that has finished execution?
Reading through some documentation, I found this works:
myOldThread = thread(foobar);
I assume there's still quite a bit of performance overhead, but at least I can reuse the same variable. :/
An alternative approach would be to never let the thread die (have a loop with a 200ms delay that checks a mutex-protected boolean for when it should run again). Not super clean, but if performance matters, this is probably the best way to do this.
Related Topics
Link Errors Using <Filesystem> Members in C++17
Typeid' Versus 'Typeof' in C++
Are C++11 Thread_Local Variables Automatically Static
What Is the Fastest Way to Change a Key of an Element Inside Std::Map
Why Is Std::Fill(0) Slower Than Std::Fill(1)
How Does Openmp Handle Nested Loops
Generating M Distinct Random Numbers in the Range [0..N-1]
Exception Safety and Make_Unique
How Typedef Works for Function Pointers
Why Does C++ Not Let Baseclasses Implement a Derived Class' Inherited Interface
C++ Inherit from Multiple Base Classes with the Same Virtual Function Name
How to Copy the Contents of an Array to a Std::Vector in C++ Without Looping
Netbeans 7.2 Shows "Unable to Resolve Identifier" , Although Build Is Successful
Debugging Template Instantiations