Having somewhat languished unchanged for a couple of years, the Boost Thread library (boost.org) finally got some of the big changes it deserved with a major rewrite for the April 2008 release of Boost 1.35.0. Hot on the heels of 1.35.0 is the Boost 1.36.0 release in August 2008, which includes even more improvements to the Thread library. Certainly, a lot has changed since William Kempf wrote The Boost.Threads Library in 2002.
These releases have included some significant changes that either bring the library more in line with the proposals for the new C++0x thread library, or provide additional features as extensions. In this article, I present an overview of the new features and changes in the 1.35.0 and 1.36.0 releases from the user's point of view.
Launching Threads
As in prior releases of Boost, threads are started by constructing instances of boost::thread
. However, there are a few notable changes to the boost::thread
class.
One of the most significant changes is that boost::thread
objects are now moveable. Taking advantage of the new rvalue-
reference facility from C++0x where available (recent versions of GCC, for instance), and with a library-based move
facility for other compilers, ownership of a specific thread of execution can be transferred between instances of boost::thread
. This means that you can return objects of type boost::thread
from a function, and store them in arrays or move
-aware containers. This lets you encapsulate the thread creation process in a function without having to dynamically allocate the thread
object.
boost::thread create_thread() { void some_function(); boost::thread t(some_function); return boost::move(t); } boost::thread threads[45]; threads[12]=boost::move(create_thread());
The second change is that you can now pass additional arguments to the boost::thread
constructor, which are in turn passed on to the thread function:
void thread_func (int i,double d,std::string s); boost::thread t(thread_func, 42,3.141,"hello world");
This works exactly like boost::bind
in fact it uses boost::bind
internally so you can even pass member functions and a "this
" pointer. It is important to note that the supplied arguments (including the thread
function itself, if it's a function object) are copied into the newly created thread, so if you need to pass a reference you have to wrap it in boost::ref
.
int i; void thread_func(int& j); boost::thread t (thread_func,boost::ref(i));
For copyable types such as int
, failure to use boost::ref
will not be diagnosed, as the code just passes a reference to the copy of the original stored in the thread, silently giving unexpected results. Therefore, if your thread function takes its parameters by reference, you need to take extra care to ensure that boost::ref
is used correctly.