7

How to wait until C++ 11 thread is started after it was created? It doesn't seem to have any method for that, unlike some other threading libraries (like Qt) that offer a special method to check if thread is running or not.

Rapptz
  • 20,807
  • 5
  • 72
  • 86
Violet Giraffe
  • 32,368
  • 48
  • 194
  • 335
  • 3
    What's your use case for this? – Casey Aug 14 '13 at 20:31
  • Yes, please describe use case. C++11 threads are "started" as soon as they are created. Do you want to extend the threads API with some notion of "alive/in-progress" vs. "terminated/finished"? Do you want to synchronize thread activity with another? Do you want new threads to be "paused" until explicitly started? Etc. – pilcrow Aug 14 '13 at 20:53
  • 3
    What does "actually start" mean? – Casey Aug 14 '13 at 21:31
  • Assume even that there was a method that told you whether a thread was running. That result can change _while_ the method is returning, so the answer would be outdated anyway before you get the result. And if you just want to know whether a thread _has_ run at all, set a variable in the thread. – MSalters Aug 15 '13 at 07:23
  • I have a use case.I have an app with a Start button. If clicked, it tries to stop the currently running thread before starting a new one. So, the problem is that if I exit from Start function right after I have created the thread, then I receive a new Stop call... which gets stuck waiting on join() after `pthread_cond_signal`. Anyway, it seems not logically correct to return from Start function and claim that the thread is running and can be stopped, when the thread is actually not yet inside its mutex+cond wait loop and thus cannot be stopped yet. – JustAMartin Jan 31 '17 at 17:42
  • @pilcrow that would require defining "started". It doesn't mean the thread is actually scheduled by the OS to "run now". It just means the OS scheduler has accepted the request for the thread to start running some time in the future. Sometimes this can take _seconds_ (depends on system load, configuration, other process activity etc)! (forever) – Gizmo Feb 18 '21 at 07:32
  • @Gizmo, yes, clarification would help, and that's what I was asking as I recall. – pilcrow Feb 18 '21 at 14:31

2 Answers2

12

The language definition requires that the new thread has started before the constructor returns. Formally, that's [thread.thread.constr] /5: "The completion of the invocation of the constructor synchronizes with the beginning of the invocation of the copy of f."

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • I think this is misinterpretation of the information. Last weeks I have been debugging shutdown issues. It seems threads can be started, and considered alive, but the OS scheduler can choose to not run the threads until a later time (it can even start the thread just when your application decides to shut down/close). I think OP wants to wait for the thread to actually start execution. This rule does not enforce that for the constructor. If this rule was true, then if would be required that a synchronized `cout` should _always_ print after `thread` constructor, but that's not the case. – Gizmo Feb 18 '21 at 07:29
  • @Gizmo -- it is not a misinterpretation. I was deeply involved in the design of threads for the C++ standard. Your points are about **implementation**, not about requirements, and you may well be right that some implementations don't meet the specification. If that's the case, complain to your compiler vendor. – Pete Becker Feb 18 '21 at 13:54
  • 1
    I know this is an old thread - I was brought in here by google search. I would strongly disagree with your statement. @Gizmo is right in this case. This has nothing to do with the compiler, but rather with the OS scheduler deciding to delay the start of a newly spawned thread. I've seen this in all major compilers. I don't really care what the wording of the language definition is. All I care is an actual behavior, which does not corresponds to the actual answer. In fact, there is no way for compiler vendors to make sure the function has started its execution before returning from the ctor. – Quest Sep 05 '21 at 18:22
  • @Quest -- if you need that fine a level of control, you're going to have to deal with the OS for it. The C++ language requirement is that the thread "has started", as in, has been created and begun executing. If the OS immediately switches away from it, as you say, there's nothing the library can do. – Pete Becker Sep 05 '21 at 18:55
  • And I think this is exactly what OP was looking for (and what gizmos comment was about). Anyway this is an old thread after all. Just wanted to share my 2c. – Quest Sep 05 '21 at 19:00
  • @Quest: yes, that's what I was looking for, thank you for your remarks. I have not found a better solution than `std::atomic_bool` that is initialized to false and then switched to true by the thread function itself as the first line of code. The library could very well enforce the behavior described by Pete Becker by providing its own thread function that wraps around the user-supplied one and does the synchronization. But that would be inefficient for use cases that do not require this behavior. – Violet Giraffe Jan 17 '23 at 15:33
  • @VioletGiraffe -- I think you missed the point of my comment. The standard **requires** that the user's function has started executing before the `std::thread` constructor returns. There's a fair amount of mechanism involved in starting a thread, and ensuring that the function has begun executing doesn't introduce any significant overhead. If the scheduler switches away from the thread after the user's function has begun executing there's nothing you can do about it; having an atomic bool doesn't help, because the scheduler can switch away from the thread immediately after you set the bool. – Pete Becker Jan 17 '23 at 17:04
6

I'm not sure why do you need to wait for it to start in a first place, but if you do, then you must use a mutex, a condition, and a flag indicated whether it is started or not. In a newly created thread, lock the mutex, set flag to «true» and notify waiter(s) on a conditional variable. In the code that creates a thread, lock the mutex, and check the flag. If the flag is «true» - your thread is started, if it is «false» then wait on a conditional variable and repeat once woken up.

  • Thanks. I was hoping there's a better solution I'm missing, but I guess not. – Violet Giraffe Aug 14 '13 at 20:23
  • Or use a waitable object, like an event in Win32, then you don't need the mutex or the flag, just the event acting as the conditional. Or, just use a bool flag by itself, and have the creating thread loop until the flag is set. No need to lock it. – Remy Lebeau Aug 14 '13 at 20:24
  • @pilcrow: and if not? – Violet Giraffe Aug 14 '13 at 20:39
  • You could also use a `boost::barrier`: http://www.boost.org/doc/libs/1_54_0/doc/html/thread/synchronization.html#thread.synchronization.barriers.barrier – Chad Aug 14 '13 at 20:42
  • 2
    @VioletGiraffe, if not, [you might not like the runtime behavior](http://stackoverflow.com/a/14625122/132382). – pilcrow Aug 14 '13 at 20:47
  • @VioletGiraffe: There is a better solution — just don't do it. Seriously, I've never seen a case where something like this is a good idea. –  Aug 14 '13 at 20:59
  • @VioletGiraffe: thank for the link, I hadn't thought about the caching issue across processors. – Remy Lebeau Aug 14 '13 at 20:59
  • @VladLazarenko: I have a use case in one of my apps. A thread initializes and talks to an external hardware API. Another thread also sometimes needs to access the same API. App startup creates the main API thread and waits for it to signal that the API is ready for use, before then creating other threads (and no, moving the API initialization logic prior to the creation of the API thread is not an option in this project). – Remy Lebeau Aug 14 '13 at 21:04
  • 1
    @RemyLebeau: It doesn't mean you have to wait for a thread to be started. It sounds like you need to synchronize access to your API, that's all. Because just the fact that a thread is started does not mean the API is initialized and is ready to be used, etc. Think twice before you do this, really. –  Aug 14 '13 at 21:06
  • @vlad: in my case, it does, because the other threads cannot touch the API until the first thread has finished initializing it, which takes multiple API calls to perform, and then that same thread monitors the API for activity. The app's current architecture does not allow the API to be synced or isolated. I can't hold up the other threads once they start running, but I can hold up when they are created, so the app waits for the main API thread to flag when the API is ready, then the app is free to create the other threads so they can access the API immediately. – Remy Lebeau Aug 14 '13 at 22:35
  • @Remy one more time - it does not. Finishing initializing API and having a thread started are two different things –  Aug 14 '13 at 23:58
  • @VladLazarenko: I think you are completely misunderstanding what I am describing. Whatever. This has gone beyond the scope of the original question. There *are* valid use cases for wanting a creating thread to wait for a created thread to actually start running. I will leave it at that. – Remy Lebeau Aug 15 '13 at 01:37
  • @RemyLebeau: Yeah, whatever. I am the last person who'd be worrying about it anyway :) –  Aug 15 '13 at 02:23