12.4. Initializing Shared Resources Once
Problem
You have a number of threads that are using a resource that must only be initialized once.
Solution
Either initialize the resource before the threads are started, or if you can’t, use
the call_once
function defined in <boost/thread/once.hpp>
and the type once_flag
. Example
12-5 shows how to use call_once
.
Example 12-5. Initializing something once
#include <iostream> #include <boost/thread/thread.hpp> #include <boost/thread/once.hpp> // Some sort of connection class that should only be initialized once struct Conn { static void init() {++i_;} static boost::once_flag init_; static int i_; // ... }; int Conn::i_ = 0; boost::once_flag Conn::init_ = BOOST_ONCE_INIT; void worker() { boost::call_once(Conn::init, Conn::init_); // Do the real work... } Conn c; // You probably don't want to use a global, so see the // next Recipe int main() { boost::thread_group grp; for (int i = 0; i < 100; ++i) grp.create_thread(worker); grp.join_all(); std::cout << c.i_ << '\n'; // c.i_ = 1 }
Discussion
A shared resource has to be initialized somewhere, and you may want the first thread
to use it to do the initializing. A variable of type once_flag
(whose exact type is platform-dependent) and the call_once
function can keep multiple threads from
re-initializing the same object. You have to do two things.
First, initialize your once_flag
variable to the macro BOOST_ONCE_INIT
. This is a platform-dependent value. In Example 12-5, the class Conn
represents some sort ...
Get C++ Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.