Boost logo

Boost Users :

From: Hal Vaughan (hal_at_[hidden])
Date: 2008-03-17 09:42:46


I apologize if this gets posted more than once. I found the group on
GMane, tried to post, joined the email list, then tried to post several
times but still have yet to see it show up.

I'm learning C++ and found a tutorial on threads with Boost on Dr.
Dobb's site.  I've copied the code from this url:

 http://www.ddj.com/cpp/184401518?pgno=5

It's supposed to fill a buffer with data on one thread and remove data
on the other thread.  I would expect it to add data and remove at
almost the same time but when I run it, it adds 10 items, then removes
them, then adds ten again, and so on.  It's never adding and removing
in an "interleaved" fashion.  I've also tried the same with simple
counters where both threads count to ten, but it doesn't seem to make a
difference.  It seems no matter how I set it up, one thread either
completes, or runs until it has to stop for a mutex, then the other
thread runs.  It seems that there is never a case of both threads
running at the same time.  I've never had trouble doing this in Perl
with fork() so I'm not at all sure what could be going wrong.

As I said, it's not just the program below, it seems to be any program
that uses more than one thread.

Am I doing something wrong or is there a setting I need to change?

I'm compiling it with "g++ -lboost_thread mthrd.cpp -o mthrd
&& ./mthrd";

Thanks!

Hal
------
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <iostream>

const int BUF_SIZE = 10;
const int ITERS = 100;

boost::mutex io_mutex;

class buffer
{
public:
  typedef boost::mutex::scoped_lock
    scoped_lock;
   
  buffer()
    : p(0), c(0), full(0)
  {
  }
   
  void put(int m)
  {
    scoped_lock lock(mutex);
    if (full == BUF_SIZE)
    {
      {
        boost::mutex::scoped_lock
          lock(io_mutex);
        std::cout <<
          "Buffer is full. Waiting..."
          << std::endl;
      }
      while (full == BUF_SIZE)
        cond.wait(lock);
    }
    buf[p] = m;
    p = (p+1) % BUF_SIZE;
    ++full;
    cond.notify_one();
  }

  int get()
  {
    scoped_lock lk(mutex);
    if (full == 0)
    {
      {
        boost::mutex::scoped_lock
          lock(io_mutex);
        std::cout <<
          "Buffer is empty. Waiting..."
          << std::endl;
      }
      while (full == 0)
        cond.wait(lk);
    }
    int i = buf[c];
    c = (c+1) % BUF_SIZE;
    --full;
    cond.notify_one();
    return i;
  }
   
private:
  boost::mutex mutex;
  boost::condition cond;
  unsigned int p, c, full;
  int buf[BUF_SIZE];
};

buffer buf;

void writer()
{
  for (int n = 0; n < ITERS; ++n)
  {
    {
      boost::mutex::scoped_lock
        lock(io_mutex);
      std::cout << "sending: "
        << n << std::endl;
    }
    buf.put(n);
  }
}

void reader()
{
  for (int x = 0; x < ITERS; ++x)
  {
    int n = buf.get();
    {
      boost::mutex::scoped_lock
        lock(io_mutex);
      std::cout << "received: "
        << n << std::endl;
    }
  }
}
   
int main(int argc, char* argv[])
{
  boost::thread thrd1(&reader);
  boost::thread thrd2(&writer);
  thrd1.join();
  thrd2.join();
  return 0;
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net