is thre any relieable way in c++11 to detect if the current thread is the main thread? Or would I have to manually save the main threads thread id with std::this_thread::get_id() and then have a routine like this:
bool isMainThread()
{
return theMainThreadIdISavedOnProgramStart == std::this_thread::get_id();
}
Is there a common way to do this? Would the above solution work?
Thanks
What do you mean by main thread? If you mean, the thread which executes main(), then there is no way you can know if a thread is a main thread or not. You've to save its ID and later on you can use the saved ID to know if a current thread is a main thread or not, by comparing its ID with the saved ID (as you guessed in your question).
To explain it a bit more, threads do not have hierarchy, there is no parent thread, no child thread even if one thread creates the other threads. The OS doesn't remember which threads created by which thread. Therefore, all threads are same to the OS, and to your program. So you cannot infer a main thread, by detecting if the current thread is the parent of all other threads in your application.
Related
I have tried searching many ways for the solution, but couldn't find proper one, so far.
I am using detached thread because I don't want my main thread to wait/block for the new child thread as it has many other important things to do.
I create a thread as follows:
std::thread rsync_t(&PreCompile::RunPreCompileThr, obj, arg1, arg2);
rsync_t.detach();
Now, Objective is to periodically check if this detached thread is active and running.
I tried future/promise and async way to do this, but it requires .get() which is something similar to join(), which I don't want.
Any suggestions to do this?
Thanks in advance.
Once you detach a thread, then you have explicitly said "I don't need to wait for this thread to finish". This is usually because the thread never finishes, and keeps running until the end of the program.
In any case, std::thread doesn't provide a mechanism to poll to see if a thread has finished without waiting. To do that you would need to use an alternative mechanism, whether the thread is detached or not.
One option is to start the thread with std::async(std::launch::async, func) and use the returned future to check if the thread is still running.
auto future=std::async(std::launch::async,thread_func);
bool thread_is_still_running=future.wait_for(std::chrono::seconds(0))!=std::future_status::ready;
If you use this option then you will need to keep the future object around (e.g. by storing it in a long-lived std::vector or a global variable), as its destructor will wait for the thread to finish.
Alternatively you can use a std::mutex and a boolean flag, or a std::atomic<bool> which is set from within the thread just before it exits, to indicate when the thread is done.
std::atomic<bool> done=false;
void thread_func(){
do_stuff();
done=true;
}
With std::async, you have an option to retrieve task status from the future. It is not necessary to use get().
https://en.cppreference.com/w/cpp/thread/future/wait_for
auto status = future.wait_for(std::chrono::milliseconds(1));
if (status == std::future_status::ready) {
// Thread has finished
}
If you detach a std::thread, you lose the communication channel that the std::thread object provides:
https://en.cppreference.com/w/cpp/thread/thread/detach
After calling detach *this no longer owns any thread.
If you want to communicate with the detached thread afterwards in any way, you need to do it manually. std::thread can no longer help you after detach.
I am using detached thread because I don't want my main thread to wait/block for the new child thread as it has many other important things to do.
The proper solution likely does not involve detach. You don't need to detach to have the thread run in parallel, it runs in parallel already when the std::thread constructor returns. Just keep the std::thread object alive and query through it, and only call join when the thread is actually supposed to be done/end. That said, std::thread only provides joinable which only changes after join, so it doesn't provide the information you need (that your code is "done" in some form).
Is there a way in c++ to get the id of the "main" program thread?
I see that std::this_thread::get_id() gets the id of the currently executing thread but I need the id of the main, original program thread. I don't see any function to get this.
The reason is that I have some non thread safe internal functions that must only be called on the original thread of the application so to be safe I want to do :-
assert(std::this_thread::get_id() == std::main_thread::get_id());
But there of course isn't a function to do that, and I can't see any way to get that information.
You could save it while this_thread is still the original thread:
std::thread::id main_thread_id;
int main() {
main_thread_id = std::this_thread::get_id(); // gotcha!
/* go on */
}
This topic seems to be discussed quite a few times here, like in this topic:
Getting a handle to the process main thread
You can find some solutions, but I'd just think the other way round... When starting the new threads, just supply the id of the main thread to them, and store that in a field in the other threads. If that is not going to change throughout the threads' life, you're good to go, you can reference the "main" thread by those handles.
pthread_self() is to get your own thread id. It doesn't seem like you can get the thread id of the thread which spawned you unless it was given to you during spawning. Or is there a way?
No, all threads are equal in POSIX threads, there is no hierarchy. Even the thread that executes main has no special role and can be terminated without effecting the others.
I put up many threads running. At a later time, I'd like to check if these threads are still alive (i.e., not finished yet and not terminated unexpectedly).
What kind of information should I keep track of regarding the threads in the first place. Thread ID, process ID, etc? How should I get these IDs?
When I need to check the liveness of these threads, what functions should I use? Will pthread_kill work here? pthread_kill takes an opaque type pthread_t as parameter, which I believe is typically an unsigned long. Is pthread_t different from a thread ID? I assume a thread ID would pick up an int as its value. In some tutorials on pthread, they assign an integer to a pthread as its ID. Shouldn't the thread get its ID from the operating system?
A thread's entire identity resides in pthread_t
Initializing a thread returns its pthread_t typed ID to its parent
Each thread can get it's own ID with pthread_self()
You can compare thread IDs using the function:int pthread_equal (pthread_t, pthread_t)
So: Maintain a common data structure where you can store thread status as STARTED, RUNNING, FINISHED using the pthread_t IDs and pthread_equal comparison function to differentiate between the threads. The parent sets the value to STARTED when it starts the thread, the thread itself sets its own state to RUNNING, does its work, and sets itself to FINISHED when done. Use a mutex to make sure values are not changed while being read.
EDIT:
You can set up a sort of 'thread destructor' using pthread_cleanup_push:
http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cleanup_pop.html
i.e. register a routine to be called when the thread exits (either itself, or by cancellation externally). This routine can update the status.
When you call pthread_create, the first argument is a pointer to a pthread_t, to which pthread_create will assign the thread ID of the newly created thread. If you want to get the thread ID of the current thread, use pthread_self(). This is the only identifying piece of information you need for the thread because all threads created this way share the same process ID.
The way you would check whether a thread is alive depends on what you need this information for. If you just want to wait until the thread has completed, you call pthread_join with the thread ID as the first argument and a pointer to a location for the return value of the thread function as the second argument. Unless you detach the threads you create by calling pthread_detach(pthread_self()) in the thread, you need to call pthread_join on them eventually so that they don't continue to hold on to their stack space.
If for some reason you want to do something while the thread is running, you could create a global variable for each thread that that thread changes when it terminates, and check that variable with the main thread. In that case, you would probably want to detach the threads so that you don't also have to join them later.
I was doing some multithreaded programming in Visual studio C++ using the calls beginthreadex, endthreadex.
I create a child thread thread1. The child thread runs on a function which never exits as it has an infinite loop. Now if the parent thread terminates with error or finishes successfully, does the child thread also exit? My doubt is - is there any situation where the child thread is alive even after the main program exits?
For linux how should this case be?
There is no parent/child relationship between threads. If thread A creates thread B and then thread A terminates, then thread B will continue to execute.
The exception to this is when the main thread (that is, the thread that runs the main() function) terminates. When this happens, the process terminates and all other threads stop.
Since C and C++ mandate that returning from the main function kills all running threads, yes, the process should be gone. And since that behavior is done by the runtime the situation should be the same on Linux.
As soon as your process die, all the resources are being released (memory, files and threads)
The correct way to do this: when you call beginthread, keep the returned handle in the parent thread, and call WaitForObject before you leave the program (we join the parent thread with the child thread).
The parent thread will block until the child thread finish. If your child thread has a infinite loop, you could define an "interruption point" , and check if you should leave. For example, using a shared boolean variable. Check Interrupt Politely fro more info.