Reputation: 11651
In the following example i am using boost ASIO , here a thread is ready and always waiting for a job to do.It will always do jobs linearly (as if jobs are stored in a queue as I understand) The following code snippet explains my point.
void WorkerThread( boost::shared_ptr< boost::asio::io_service > io_service )
{
io_service->run();
}
void PrintNum( int x )
{
//Do somejon
}
boost::shared_ptr< boost::asio::io_service > io_service( new boost::asio::io_service);
boost::shared_ptr< boost::asio::io_service::work > work(new boost::asio::io_service::work( *io_service ));
boost::asio::io_service::strand strand( *io_service );
worker_threads.create_thread( boost::bind( &WorkerThread, io_service ) );
//Give the thread (which is already active) some work to do
for(int i=0;i<2;i++)
{
strand.post( boost::bind( &PrintNum, i ) );
}
Question 1
Now my question is whether the above method is faster and more efficient than launching independents thread (for instance by using boost::thread
) I know in case of independent threads such as by boost::thread
the launching of threads may not be linear (thread 2 might run before thread 1) my question is in case there was only one thread involved which mechanism would have been faster ? Is there any overhead becaus eof boost::bind
Question 2 In the above example 2 threads are launched that wait for work (thread1 and thread2). Now I wanted to know what exactly happens when 2 work is consecutively given as such
for(int i=0;i<2;i++)
{
strand.post( boost::bind( &PrintNum, i ) );
}
Each thread gets one job however thread 2 wont complete before thread 1 . My questions is what happens with thread 2 while thread one is lauching does it even enter the PrintNum
method while thread one is lauching. What is the point of having more than one thread then in such a case when it comes to performance?
Upvotes: 0
Views: 122
Reputation: 3403
Threads and asynchronous i/o are not performance optimizations. They are techniques used to hide latency.
Question 1: boost::bind is relatively cheap. It just creates a function object. Launching threads is extremely expensive. Synchronizing between threads is somewhat expensive (not as expensive as creating a new thread, but more expensive than creating a function object). Operations like strand.post() are presumably doing a lot of synchronization (communicating values between threads, making sure that things happen in particular orders).
Question 2: Thread 2 (assuming that the library creates it rather than optimizing it away somehow) will block waiting for thread 1 to finish doing its processing before thread 2 even calls PrintNum.
There is no point in having two threads if they are going to spend most of their time blocking for each other.
Sequences of dependent operations should for the most part be mapped to the same thread. (Like PrintNum(0); PrintNum(1) in your case: you want them to run in order, so put them in the same thread.)
Only start a new thread if you have something to do that is almost completely independent of what you are currently doing. An example would be: you are writing a server that makes connections with multiple users or devices. Since each user or device is working at its own speed, requesting service or responding to questions from the server, then you might want to create a thread to interact with each user or device. That way if one user goes away for a few minutes all the other users can continue to interact with their thread without blocking waiting for the user that is away. But the service you perform for an individual user goes in a certain order ("user asks for A, so I look up A, do some processing on it then send it back to the user") so don't divide up the service you perform for one user into different threads.
Upvotes: 1