Archive

Posts Tagged ‘thread’

boost::thread and std::list

June 22nd, 2009 4 comments

I had to create many threads in C++. Of course I didn’t want to use pthread, because it’s ugly C. I chose boost::thread instead. Then I needed some container to keep all these threads. Arrays were out of the question for the same reason as pthread. I could use boost:array but stl::list was easier.

The problem was—how to keep this thread objects? I couldn’t use std::list<boost::thread> nor std::list<boost::thread &> because threads cannot be copied. I had to dynamically create the object in order to prevent the destruction after the scope. But for some reason I got compiler error while trying std::list< std::auto_ptr<boost::thread> > in the line where I pushed_back newly created threads.

The cause of the error was that the argument of std::list::push_back() was a constant reference. And while assinging one auto_ptr to another, the first one is getting call release() method, but it can’t since the reference is constant and release() change the state of the object.

To solve this problem one can use boost::shared_ptr.

Example:

#include <iostream>
#include <list>
#include <boost/thread.hpp>
#include <boost/date_time.hpp>
#include <boost/smart_ptr.hpp>
 
using std::list;
using std::cout;
using std::endl;
 
struct foo
{
	void operator() (int id)
	{
		cout << "starting thread " << id << '\n';
		boost::this_thread::sleep(boost::posix_time::seconds(3));
		cout << "ending thread " << id << '\n';
	}
};
 
int main()
{
	typedef boost::shared_ptr<boost::thread> thread_ptr;
	list<thread_ptr> thread;
 
	cout << "creating threads\n";
 
	for (int i = 0; i < 10; ++i)
	{
		thread.push_back(boost::shared_ptr<boost::thread>(new boost::thread(foo(), i)));
	}
 
	cout << "after creation, now joining them\n";
 
	for (list<thread_ptr>::iterator it = thread.begin(); it != thread.end(); ++it)
	{
		(*it)->join();
	}
 
	cout << "ending program" << endl;
 
	return 0;
}

And the result:

tomek@notlob:~% g++ -o threads threads.cpp -O2 -Wall -lboost_thread-mt
tomek@notlob:~% ./threads
creating threads
starting thread 1
starting thread 0
starting thread 2
starting thread 3
starting thread starting thread 4
5
starting thread 6
starting thread 7
starting thread 8
starting thread 9
after creation, now joining them
ending thread 1
ending thread 3
ending thread 5
ending thread 4
ending thread 0
ending thread 2
ending thread 6
ending thread 8
ending thread 7
ending thread 9
ending program