|
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