
Can the yield function of boost::thread be used to immediately wake up a thread that is sleeping? I would like to use this to make sure that certain threads get the chance to exit before the process terminates, without join resulting in the whole program sleeping. -Jason

Jason Hise <chaos@ezequal.com> writes:
Can the yield function of boost::thread be used to immediately wake up a thread that is sleeping? I would like to use this to make sure that certain threads get the chance to exit before the process terminates, without join resulting in the whole program sleeping.
No. I am currently exploring ideas around waking specific threads on win32 as an implementation detail of various boost::thread primitives, but I am not aware of ways to do this on other platforms, such as those using pthreads. Anthony -- Anthony Williams Software Developer Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk

Jason Hise wrote:
Can the yield function of boost::thread be used to immediately wake up a thread that is sleeping? I would like to use this to make sure that certain threads get the chance to exit before the process terminates, without join resulting in the whole program sleeping.
Join only blocks the current thread, not the whole program. If you want thread X to exit before the process is terminated (via a return from main, for instance), then joining X before returning from main or calling exit() would be the appropriate way to accomplish that. As for yield, it's almost entirely useless.

On Sep 23, 2005, at 5:54 PM, Peter Dimov wrote:
As for yield, it's almost entirely useless.
<mischievous> I have one admittedly contrived benchmark that was sped up by over a factor of two by inserting yields in strategic places (but only on multiprocessor architectures). :-) The lesson I took away from that experience is that there are situations where cooperative multitasking is actually superior to preemptive multitasking and yield is a good way for preemptive multitasking to gain that advantage back. </mischievous> Btw, I agree 100% with you about join. I just couldn't resist the yield comment (and kudos for inserting the "almost" in there). :-) -Howard

Peter Dimov wrote:
Jason Hise wrote:
Can the yield function of boost::thread be used to immediately wake up a thread that is sleeping? I would like to use this to make sure that certain threads get the chance to exit before the process terminates, without join resulting in the whole program sleeping.
Join only blocks the current thread, not the whole program. If you want thread X to exit before the process is terminated (via a return from main, for instance), then joining X before returning from main or calling exit() would be the appropriate way to accomplish that.
The problem is that joining x before main exits forces the process to wait until x is done sleeping before main can exit. If there is no way to wake up a sleeping thread, then it appears my only option is to sleep for very short intervals and keep checking two conditions to see if sleeping should stop (time elapsed, or early wakeup signaled). Unfortunately, that will be expensive not only because the thread can't sleep 'soundly', but also because each time I want to check if the wake up signal has been triggered I need to acquire a lock. Plus, while I am waiting for that lock the time could elapse and I would still be waiting. Is there any other way to pull this off? -Jason

Jason Hise <chaos@ezequal.com> writes:
Peter Dimov wrote:
Jason Hise wrote:
Can the yield function of boost::thread be used to immediately wake up a thread that is sleeping? I would like to use this to make sure that certain threads get the chance to exit before the process terminates, without join resulting in the whole program sleeping.
Join only blocks the current thread, not the whole program. If you want thread X to exit before the process is terminated (via a return from main, for instance), then joining X before returning from main or calling exit() would be the appropriate way to accomplish that.
The problem is that joining x before main exits forces the process to wait until x is done sleeping before main can exit. If there is no way to wake up a sleeping thread, then it appears my only option is to sleep for very short intervals and keep checking two conditions to see if sleeping should stop (time elapsed, or early wakeup signaled). Unfortunately, that will be expensive not only because the thread can't sleep 'soundly', but also because each time I want to check if the wake up signal has been triggered I need to acquire a lock. Plus, while I am waiting for that lock the time could elapse and I would still be waiting. Is there any other way to pull this off?
This sounds like a prime target for the use of a condition variable to me. You can wait on a condition variable, then signal the condition variable to wake the sleeping thread. Yes it means acquiring a lock, but most thread synchronization requires some form of lock. Anthony -- Anthony Williams Software Developer Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk

On Sep 23, 2005, at 6:37 PM, Jason Hise wrote:
Peter Dimov wrote:
Jason Hise wrote:
Can the yield function of boost::thread be used to immediately wake up a thread that is sleeping? I would like to use this to make sure that certain threads get the chance to exit before the process terminates, without join resulting in the whole program sleeping.
Join only blocks the current thread, not the whole program. If you want thread X to exit before the process is terminated (via a return from main, for instance), then joining X before returning from main or calling exit() would be the appropriate way to accomplish that.
The problem is that joining x before main exits forces the process to wait until x is done sleeping before main can exit. If there is no way to wake up a sleeping thread, then it appears my only option is to sleep for very short intervals and keep checking two conditions to see if sleeping should stop (time elapsed, or early wakeup signaled). Unfortunately, that will be expensive not only because the thread can't sleep 'soundly', but also because each time I want to check if the wake up signal has been triggered I need to acquire a lock. Plus, while I am waiting for that lock the time could elapse and I would still be waiting. Is there any other way to pull this off?
Ideally you would use a system by which the all threads which can't proceed sleep and all threads which can proceed don't sleep. If the main thread can't exit because of an ongoing worker thread, then it sleeps, and one would hope that if no other threads are contending, this would force the worker thread awake to complete its task. If join isn't behaving as above, there is a bug, perhaps in boost code, perhaps in the OS below boost code. Or are we talking about a worker thread that has been forced to sleep for X amount of time? I.e. part of its task is to sleep. If so, why is that worker thread forced to sleep, and perhaps having it sleep on a condition variable would be better? -Howard

Howard Hinnant wrote:
Or are we talking about a worker thread that has been forced to sleep for X amount of time? I.e. part of its task is to sleep. If so, why is that worker thread forced to sleep, and perhaps having it sleep on a condition variable would be better?
Alright, I will add some more context to the discussion. This is being used for a 'timeout lifetime' for the singleton library. The idea is that a singleton which is cheap to create but expensive to hold on to could automatically be destroyed if it goes unused a certain amount of time, and be recreated the next time it is needed. To implement this idea I create a timeout thread when the instance is created, and force that thread to sleep until the timeout time is reached. If at that point the timeout time has been extended, the thread sleeps again, otherwise it destroys the instance and exits. The problem is that if the process is exiting I would like to force the thread to wake up and time out early to ensure that the singleton get destroyed. Anthony Williams wrote:
This sounds like a prime target for the use of a condition variable to me. You can wait on a condition variable, then signal the condition variable to wake the sleeping thread. Yes it means acquiring a lock, but most thread synchronization requires some form of lock.
I am relatively new to threading, so forgive me if my question is naive, but what is the formal definition of a condition variable? If a condition variable is capable of making a thread that has been explicitly told to sleep until a certain time wake up early, can you show me an example of its use? Thanks. -Jason

Jason Hise wrote:
Alright, I will add some more context to the discussion. This is being used for a 'timeout lifetime' for the singleton library. The idea is that a singleton which is cheap to create but expensive to hold on to could automatically be destroyed if it goes unused a certain amount of time, and be recreated the next time it is needed. To implement this idea I create a timeout thread when the instance is created, and force that thread to sleep until the timeout time is reached. If at that point the timeout time has been extended, the thread sleeps again, otherwise it destroys the instance and exits.
The problem is that if the process is exiting I would like to force the thread to wake up and time out early to ensure that the singleton get destroyed.
Instead of sleeping, use timed_wait on a condition variable. Upon awakening, check the cause (which could be timeout, valid signal, or spurious wakeup).

On Sep 23, 2005, at 7:43 PM, Jason Hise wrote:
I am relatively new to threading, so forgive me if my question is naive, but what is the formal definition of a condition variable? If a condition variable is capable of making a thread that has been explicitly told to sleep until a certain time wake up early, can you show me an example of its use?
On Sep 23, 2005, at 8:52 PM, Peter Petrov wrote:
Instead of sleeping, use timed_wait on a condition variable. Upon awakening, check the cause (which could be timeout, valid signal, or spurious wakeup).
<nod> I remember well my first introduction to condition variables. At first they seemed rather strange. But I view them now as fundamental as a mutex (from a client's point of view). You just can't live without them. I could've sworn boost had a good example or two of condition usage, but I'm not finding one tonight. So here's a bounded_queue demo I wrote some time ago. It's a copy/paste from example code and it uses Metrowerks::condition and such. You can just substitute "boost" for "Metrowerks" and you ought to be pretty close with it. The basic idea is that a thread can lock a mutex, then go to sleep on a condition variable, passing it the locked mutex. The condition variable atomically unlocks the mutex, allows another thread to make the condition true (probably needing to lock the mutex), and relocks the mutex, awaking the original thread. The original thread awakes with whatever condition it needs magically satisfied (by another thread), and it's mutex locked and ready to rock & roll (but beware of spurious wake ups). There are really few libraries that are worth a full-stop and a deep-dive learning experience for a day or two. boost::condition is one of those libraries (or equivalently pthread_cond_init, pthread_cond_destroy, pthread_cond_signal, pthread_cond_broadcast, pthread_cond_wait, pthread_cond_timedwait). #include <iostream> #include <bind> #include <cdeque> #include <msl_thread> class bounded_queue { public: typedef Metrowerks::mutex Mutex; typedef Mutex::scoped_lock lock; bounded_queue(int max) {the_queue_.reserve((unsigned)max);} void send (int m); int receive(); private: Metrowerks::cdeque<int> the_queue_; Metrowerks::condition queue_is_empty_so_; Metrowerks::condition queue_is_full_so_; Mutex mut_; }; template <class C> struct container_not_full { container_not_full(const C& c) : c_(c) {} bool operator()() const {return c_.size() != c_.capacity();} private: const C& c_; }; template <class C> struct container_not_empty { container_not_empty(const C& c) : c_(c) {} bool operator()() const {return !c_.empty();} private: const C& c_; }; void bounded_queue::send (int m) { lock lk(mut_); queue_is_full_so_.wait(lk, container_not_full<Metrowerks::cdeque<int> >(the_queue_)); the_queue_.push_back(m); std::cout << "sent: " << m << '\n'; if (the_queue_.size() == 1) queue_is_empty_so_.notify_one(); } int bounded_queue::receive() { lock lk(mut_); queue_is_empty_so_.wait(lk, container_not_empty<Metrowerks::cdeque<int> >(the_queue_)); int i = the_queue_.front(); std::cout << "received: " << i << '\n'; if (the_queue_.size() == the_queue_.capacity()) queue_is_full_so_.notify_one(); the_queue_.pop_front(); return i; } bounded_queue buf(20); void sender(volatile bool& cancel) { int n = 0; while (!cancel) { buf.send(n); ++n; } buf.send(-1); } void receiver() { int n; do { n = buf.receive(); } while (n >= 0); } int main() { volatile bool cancel = false; Metrowerks::thread send(std::tr1::bind(sender, std::tr1::ref(cancel))); Metrowerks::thread receive(receiver); Metrowerks::thread::sleep(Metrowerks::elapsed_time(1)); cancel = true; send.join(); receive.join(); } -Howard

Howard Hinnant wrote:
<nod> I remember well my first introduction to condition variables. At first they seemed rather strange. But I view them now as fundamental as a mutex (from a client's point of view). You just can't live without them.
Thanks for the help and code example. I didn't realize that a condition variable was encapsulated inside the boost threads library, and not just a general design principle (when I first saw the term, I was thinking 'volatile bool' :) ). I think I should be able to make this work now. However, I would like to elaborate on a little more of what I am doing just in case people more knowledgeable about threading can offer design improvements. Because the singleton library is now being designed to work with shared memory in addition to allowing multiple instances in a singleton_map (multiton), I have a particularly difficult situation to deal with. The main problem is: when a multiton exists in shared memory, who should own the timeout threads associated with each instance? If the instance were not in shared memory, I could simply make the thread a member of the lifetime policy (there is one lifetime policy instance associated with each singleton instance). But if the lifetime policy exists in shared memory, it would be possible for the process which created the original thread to exit while the lifetime policy and singleton instance are still being used by another process. This would result in undefined behavior. If there were only one instance of the lifetime policy in shared memory I could use static bools to track which process has or has not yet created a timeout thread for that lifetime policy type, and manage the lifetime of each thread on a per-process basis. But I still have to handle multiple lifetime instances which live in shared memory. I think that the only way to do this is to create a new thread every time the instance is accessed, which causes the 'timer' to be reset. The timeout thread main function would then only sleep once, after which it would check the current timeout time, decide whether or not to destroy the instance, and immediately exit afterward (function would contain no loops). To handle the case where the process exits while some timeout threads for that process are still pending, I think I need to maintain a static (read process local) collection of thread nodes, with a destructor that signals and joins each node in the collection in turn. (Don't worry, I have the means to make sure that this destructor is triggered before the lifetime policy instance gets destroyed). To make sure that this collection doesn't grow obscenely large, I can prune the terminated threads every time a new thread is added. Although this solution will probably work, it adds the overhead of a thread creation every time the singleton instance is accessed. Is this overhead large enough to be concerned about? If so, what other options do I have? Please ask me questions if anything written above doesn't make sense. I could really use some help with this scenario, and I hope my verbose explanation of the background of the problem doesn't scare people away. :) -Jason

Jason Hise <chaos@ezequal.com> writes:
Because the singleton library is now being designed to work with shared memory in addition to allowing multiple instances in a singleton_map (multiton), I have a particularly difficult situation to deal with. The main problem is: when a multiton exists in shared memory, who should own the timeout threads associated with each instance?
How about each process that accesses the singleton having a thread that checks the timeout? Anthony -- Anthony Williams Software Developer Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk

Anthony Williams wrote:
Jason Hise <chaos@ezequal.com> writes:
Because the singleton library is now being designed to work with shared memory in addition to allowing multiple instances in a singleton_map (multiton), I have a particularly difficult situation to deal with. The main problem is: when a multiton exists in shared memory, who should own the timeout threads associated with each instance?
How about each process that accesses the singleton having a thread that checks the timeout?
Would that thread check for timeouts for each singleton instance of the same type, or each singleton instance of any type (that uses this lifetime policy)? I might be able to put together a behind the scenes timeout_registration_singleton which is unique per process and owns this thread... but perhaps it would be better to make said singleton public? Perhaps even make it customizable so that any 'resource' that meets a given interface can be registered with any timeout_singleton specified by client code? At that point it would no longer be a lifetime policy though... although that's not necessarily a bad thing. -Jason

Howard Hinnant wrote: [...]
template <class C> struct container_not_full { container_not_full(const C& c) : c_(c) {} bool operator()() const {return c_.size() != c_.capacity();} private: const C& c_; };
struct container_not_full { typedef bool result_type; template<class C> bool operator()( C const & c ) const { return c.size() != c.capacity(); } }; [...]
void bounded_queue::send (int m) { lock lk(mut_); queue_is_full_so_.wait(lk, container_not_full<Metrowerks::cdeque<int> >(the_queue_));
queue_is_full_so_.wait( lk, bind( container_not_full(), ref( the_queue_ ) ); ;-)

Jason Hise wrote:
The problem is that joining x before main exits forces the process to wait until x is done sleeping before main can exit. If there is no way to wake up a sleeping thread, then it appears my only option is to sleep for very short intervals and keep checking two conditions to see if sleeping should stop (time elapsed, or early wakeup signaled).
Can't you block on the condition variable as usual and use notify_all in the main thread to wake everyone up so that they can check the "should_exit" flag?
participants (5)
-
Anthony Williams
-
Howard Hinnant
-
Jason Hise
-
Peter Dimov
-
Peter Petrov