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 ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access