user1002288
user1002288

Reputation: 5040

boost::mutex cannot help avoid race conditions in a C++ program ?

I am doing a multhread C++ boost on Linux.

The following program still have race conditions even though I tried to use locks.

The result is 8 or 9 or 5 . it should NOT happen.

 #include <iostream>
 #include <boost/bind.hpp>
 #include <boost/threadpool.hpp>
 #include <boost/thread/mutex.hpp>
 #include <boost/thread.hpp>

 boost::mutex myMutex ;
 int g = 0 ;

 void f()
 {

    //myMutex.lock();
    {
            boost::mutex::scoped_lock lock(myMutex);
            ++g;
    }
    //myMutex.unlock();
    return ;
 }
 const int threadnum = 10;
 int main()
 {
    boost::threadpool::fifo_pool tp(threadnum);
    for (int i = 0 ; i < threadnum ; ++i)
            tp.schedule(boost::bind(f));
    std::cout << g << std::endl ;
    return 0 ;
 }

Any help will be appreciated.

thanks !

Upvotes: 0

Views: 773

Answers (3)

Ben Barden
Ben Barden

Reputation: 2111

I'm not sure I'm reading this right, but it looks like you're scheduling a bunch of things that will increment g, and then calling a cout on the contents of g. Your mutex prevents the scheduled procs from trampling over one another, but nothing forces the cout at the end to wait until they're all done. You'd need some sort of read/write mutex for that.

Upvotes: 5

Gerasimos R
Gerasimos R

Reputation: 2066

from http://threadpool.sourceforge.net/tutorial/intro.html :

It is very important to understand that the task is only scheduled for execution. Schedule returns immediately and there are no guarantees about when the tasks are executed and how long the processing will take.

You schedule 10 tasks and then immediately print the result for as many as executed by the time you reach the line

std::cout << g << std::endl ;

So, while your mutex makes sure threads increment g one at a time, you're not waiting for them to finish before printing the result. One way to modify your code is to wait for all tasks in the pool to finish:

boost::threadpool::fifo_pool tp(threadnum);
for (int i = 0 ; i < threadnum ; ++i)
        tp.schedule(boost::bind(f));
tp.wait(); //WAIT FOR TASKS TO EXECUTE
std::cout << g << std::endl ;
return 0 ;

Upvotes: 7

user1440922
user1440922

Reputation: 72

It appears that the main thread is finishing before the children are - which is why you get seemingly random values for g. There are many ways to make the main thread wait until the children are finished i.e.

Wait for tasks to get completed in threadpool

Upvotes: 0

Related Questions