
Le 25/10/12 11:13, Andrzej Krzemienski a écrit :
2012/10/23 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr>
Hi, I have created two tickets to track this possible additions:
https://svn.boost.org/trac/**boost/ticket/7540<https://svn.boost.org/trac/boost/ticket/7540>: Add a helper class that interrupts a thread and join it on destruction https://svn.boost.org/trac/**boost/ticket/7541<https://svn.boost.org/trac/boost/ticket/7541>: Add a thread wrapper class that interrupts and join on destruction
While the scoped_thread class defined in C++ Concurrency in Action is a strict scoped class that doesn't allows any change in the wrapped thread, I think that making the interface thread compatible is also a good option. This doesn't means that a strict scoped thread has no use.
Hi Vicente, The description in the two tickets above do not mention any interruption. thread_guard and scoped_thread only join w/o interruption. Do you intend both to interrupt before join?
If "yes", will the names of the two would not be confusing? Name "scoped_thread" is likely (IMHO) to be interpreted that we want to finish for the thread to end in a normal (non-interrupted) way. Perhaps the name should indicate that we want an interruption.
If "no", is scoped_thread different from the functionality offered by async? (Given that future's destructor blocks.)
I've been working a little bit these classes and I have not find that interrupt-and-join on the destructor could be a a good compromise. As others, maybe you, have signaled, each developer could need a specific action on the destruction. As always been more generic means making the class parameterized with a policy. A possible implementation could be /** * Non-copyable RAII strict thread guard joiner which join the thread if joinable when destroyed. */ class strict_thread_joiner { thread& t; public: BOOST_THREAD_MOVABLE_ONLY( strict_thread_joiner) explicit strict_thread_joiner(thread& t_) : t(t_) { } ~strict_thread_joiner() { if (t.joinable()) { t.join(); } } }; /** * RAI @c thread wrapper adding a specific StrictThreadGuard allowing to master what can be done at destruction time. * * StrictThreadGuard: A NonCopyable class that takes a @c thread& as constructor parameter. * The default is a strict thread joiner guard. * * thread std::thread destructor terminates the program if the thread is not joinable. * Having a wrapper that can join the thread before destroying it seems a natural need. * * Example: * * boost::strict_scoped_thread<> t((boost::thread(F))); * */ template <class StrictThreadGuard = strict_thread_joiner> class strict_scoped_thread { thread t_; StrictThreadGuard m_; public: BOOST_THREAD_NO_COPYABLE( strict_scoped_thread ) /// non copyable /** * Constructor from the thread to own. * * @param t: the thread to own. * * Effects: move the thread to own @c t and pass the stored thread to an internal Destroyer. */ explicit strict_scoped_thread(BOOST_THREAD_RV_REF(thread) t) : t_(boost::move(t)), m_(t_) { } }; Now it is up to the user to change the default strict_thread_joiner policy. I've implemented also a non-strict thread wrapper that behaves a thread except that for the destruction. Maybe need another name. /** * RAI @c thread wrapper adding a specific destroyer allowing to master what can be done at destruction time. * * ThreadGuard: A MoveOnly class that takes a @c thread& as constructor parameter. * The default is a thread_joiner guard. * * thread std::thread destructor terminates the program if the thread is not joinable. * Having a wrapper that can join the thread before destroying it seems a natural need. * * Remark: @c scoped_thread is not a @c thread as @c thread is not designed to be derived from as a polymorphic type. * Anyway @c scoped_thread can be used in most of the contexts a @c thread could be used as it has the * same non-deprecated interface with the exception of the construction. * * Example: * * boost::scoped_thread<> t((boost::thread(F))); * t.interrupt(); * */ template <class ThreadGuard = thread_joiner> class scoped_thread; Does this respond to your question? Best, Vicente