How to Tell Reliably If a Boost Thread Has Exited Its Run Method

How can I tell reliably if a boost thread has exited its run method?

Since you can join a thread even after it has terminated, joinable() will still return true until you call join() or detach(). If you want to know if a thread is still running, you should be able to call timed_join with a wait time of 0. Note that this can result in a race condition since the thread may terminate right after the call.

How can I tell whether a boost::thread has finished execution or not?

You should be using an eventing/notification mechanism to have the threads signal when they are done and an overall event to wait for all of them to complete. This is known as a countdown latch (see http://msdn.microsoft.com/en-us/magazine/cc163427.aspx#S1 ). You could build one using a boost condition variable and an int counter protected by a boost mutex.

An even simpler approach should be to just sequentially join on all the threads in a loop. There's no need to attempt to parallelize this since in the worst case, the first join will take longer than all other threads to complete, but by that point the rest of the joins will take zero time (because they are all done).

If you have hard dependencies on which threads are allowed to finish first and complex lifetime graphs, you should consider representing these with a class/data structure to raise the level of abstraction so that the outside waiter doesn't need to care directly about these details.

Boost thread, how can I check if a thread is still running?

The general answer would be that you can't, but if you just want to check so as to avoid blocking in join, there's a timed_join function.

Is a boost thread interruptible after termination?

Yes, it is safe to call this method.

From the documentation:

If *this refers to a thread of execution, request that the thread will
be interrupted the next time it enters one of the predefined
interruption points with interruption enabled, or if it is currently
blocked in a call to one of the predefined interruption points with
interruption enabled.

When the boost::thread object (*this) is not "a thread of execution", that means is not running, calling this method does nothing.

how to join thread if joinable do nothing otherwise?

Use the joinable() function to check whether it should be joined:

if (thread.joinable()) thread.join();

You can (in fact, you must) join a thread even if it's already finished, unless it's been detached. It's an error to join it twice, or to join an empty or detached thread.

Correct way of checking if threads are done?

You can use WaitForMultipleObjects to wait for the threads to finish in primary thread.

Boost: how to create a thread so that you can control all of its standard output, standard errors?

That feature does not exist in Boost. You can, however, use _dup2 to replace the standard out descriptor:

#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <io.h>
#include <iostream>
#include <windows.h>

int main()
{
HANDLE h = CreateFile(TEXT("test.txt"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (0 == SetStdHandle(STD_OUTPUT_HANDLE, h)) {
std::fprintf(stderr, "`SetStdHandle` failed with error %d\n", (int)GetLastError());
return EXIT_FAILURE;
}

int h_desc = _open_osfhandle((long)h, 0);
_dup2(h_desc, STDOUT_FILENO);

std::printf("test\r\n"); // This actually writes to `h`.
std::fflush(stdout);

std::cout << "another test" << std::endl; // Also writes to `h`

CloseHandle(h);
return EXIT_SUCCESS;
}

Essentially what this trick does is allow you to redirect all writes to stdout, std::cout, and GetStdHandle(STD_OUTPUT_HANDLE) to a writable handle of your choosing (h). Of course, you can use CreatePipe to create the writable handle (h) and read from the readable end in another thread.

EDIT: If you are looking for a cross-platform solution, note that this trick is even easier on POSIX-compatible systems because dup2 is a standard function in unistd.h and "writable handles" are already descriptors.

Why is my variable not changing when modified in separate thread? c++/boost

You give the thread a reference to the chunk variable, which does no longer 'exist' after exiting the for loop.

So you may see the thread changing some value, but it really dereferences some stale chunk variable, uses the (unpredictable) content as a pointer, changes the memory location of what it thinks is the changed member.

You shouldn't give it a ref. The thread needs the actual pointer, not the variable holding the pointer.



Related Topics



Leave a reply



Submit