I am learning concurrency programming, I try my best yet can't solve the problem

boost::mutex mut;
std::vector<int> int_vector;
boost::condition_variable int_cond;

void data_preparation_thread()
{
  while(int_vector.size() != 10)
  {
    std::cout<<"data preparation thread :: vector size = "<<int_vector.size()<<std::endl;
    boost::lock_guard<boost::mutex> lk(mut);
    int_vector.push_back(4);
    int_cond.notify_one();
  }
}

void data_processing_thread()
{
  while(1)
  {
    std::cout<<"front :: data processing thread :: vector size = "<<int_vector.size()<<std::endl;
    boost::unique_lock<boost::mutex> lk(mut);
    std::cout<<"back :: data processing thread :: vector size = "<<int_vector.size()<<std::endl;
    int_cond.wait(lk, boost::bind( std::equal_to<int>(),  int_vector.size(), 10) );
    std::cout<<"int_cond = true\n";
    lk.unlock();
    break;
  }
}

void testCondVar()
{
  boost::thread t1(data_processing_thread);
  boost::thread t2(data_preparation_thread);
  t1.join();
  t2.join();
}

After I call testCondVar() in main(), the results are

front :: data processing thread :: vector size = 0
back :: data processing thread :: vector size = 0
data preparation thread :: vector size = 0
data preparation thread :: vector size = 1
data preparation thread :: vector size = 2
data preparation thread :: vector size = 3
data preparation thread :: vector size = 4
data preparation thread :: vector size = 5
data preparation thread :: vector size = 6
data preparation thread :: vector size = 7
data preparation thread :: vector size = 8
data preparation thread :: vector size = 9

It never stop, it just stuck at there
How could I solve it?Is this a dead lock?
According to my understanding, if the condition variable is satisfied
The t1 thread should lock the mutex and keep going
What kind of mistakes do I make?
Thank you very much

Edited 5 Years Ago by stereomatching: n/a

I change the code a little bit and I find out something
I change the std::equal to my self-defined functor equalOut

template<typename T>
class equalOut : public std::binary_function<T, T, bool>
{
  public :
    bool const operator()(T const A, T const B) const
    {
      std::cout<<A<<", "<<B<<std::endl;
      return A == B;
    }
};

void data_processing_thread()
{
  while(1)
  {
    std::cout<<"front :: data processing thread :: vector size = "<<int_vector.size()<<std::endl;
    boost::unique_lock<boost::mutex> lk(mut);
    std::cout<<"back :: data processing thread :: vector size = "<<int_vector.size()<<std::endl;
    //int_cond.wait(lk, boost::bind( std::equal_to<int>(),  int_vector.size(), 10) );
    int_cond.wait(lk, boost::bind( equalOut<int>(),  int_vector.size(), 10) );
    int_vector.push_back(10);
    std::cout<<"int_cond = true\n";
    lk.unlock();
    break;
  }
}

The results are

front :: data processing thread :: vector size = 0
back :: data processing thread :: vector size = 0
0, 10
data preparation thread :: vector size = 0
data preparation thread :: vector size = 1
data preparation thread :: vector size = 2
data preparation thread :: vector size = 3
data preparation thread :: vector size = 4
data preparation thread :: vector size = 5
data preparation thread :: vector size = 6
data preparation thread :: vector size = 7
data preparation thread :: vector size = 8
data preparation thread :: vector size = 9
0, 10

Looks like the int_cond.notify() would not notify the t1 thread every times
Should not it always notify thread t1?
And the value of int_vector.size() is always zero
that is why thread t1 would never lock the mutexl
But I still don't know how to solve it

Edited 5 Years Ago by stereomatching: n/a

Well, I change the code as below

template<typename T, typename U = T>
class equalOut : public std::binary_function<T, U, bool>
{
  public :
    bool const operator()(T const A, U const B) const
    {
      std::cout<<A.size()<<", "<<B<<std::endl;
      return A.size() == B;
    }
};

void data_processing_thread()
{
  while(1)
  {
    std::cout<<"front :: data processing thread :: vector size = "<<int_vector.size()<<std::endl;
    boost::unique_lock<boost::mutex> lk(mut);
    std::cout<<"back :: data processing thread :: vector size = "<<int_vector.size()<<std::endl;
    //int_cond.wait(lk, boost::bind( std::equal_to<int>(),  int_vector.size(), 10) );
    //int_cond.wait(lk, boost::bind( equalOut<int>(),  int_vector.size(), 10) );
    int_cond.wait(lk, boost::bind( equalOut<std::vector<int>, int>(),  boost::ref(int_vector), 10) );
    //int_vector.push_back(10); this line may cause infinite loop
    std::cout<<"int_cond = true\n";
    lk.unlock();
    break;
  }
}

I solve the problem, but the codes are very ugly

There are still a probelm I don't understand
How could int_cond.notify_one() notify thread t1 two times only?
ps : my compiler do not support lambda expression yet

Edited 5 Years Ago by stereomatching: n/a

This article has been dead for over six months. Start a new discussion instead.