Hey everyone. I'm writing a word frequency analysis just to see how fast I can get it running. I've done just about everything I can with a sequential implementation, so I thought I might try putting the input on one thread (it reads the text to analyze from a file) and the frequency analysis on another, but I'm failing miserably. I'm using the boost thread library, and I'm quite positive it has something to do with user error.

On the input thread, I'm reading words in, parsing them, and placing them into a queue shared between the two threads. The calculation thread is *supposed* to be pulling words from the queue and adding them to a search tree as the input thread adds them, but apparently that isn't happening - after adding threading, the program takes about 50x longer to run.

Here are the input/output functions each respective thread uses (the bb global variable is the shared queue and words is the search tree):
Code:
void writer()
{
  string s = bb.receive();
  while (s.length() > 0)
  {
    words.add(s);
    s = bb.receive();
  }
}


void reader()
{
  string reader;
  string temp;

  while (file >> reader)
  {
    for (unsigned int i = 0; i < reader.length(); i++)
    {
      if (isalpha(reader[i]) || reader[i] == '\'' || reader[i] == '-')
        temp += tolower(reader[i]);
    }

    if (temp.length())
    {
      bb.send(temp);
    }

    temp.clear();
  }

  bb.send(temp);
}
Here's the declaration of the two threads:
Code:
  boost::thread input(&reader);
  boost::thread output(&writer);
  input.join();
  output.join();
... and here's the code for the bounded buffer class that serves as the internal queue:
Code:
const int BUFFER_SIZE = 1000;

class bounded_buffer : private boost::noncopyable
{
 public:
  typedef boost::mutex::scoped_lock lock;

  bounded_buffer() { begin = end = buffered = 0; }

  void send(string s)
  {
    lock l(monitor);
    while (buffered == BUFFER_SIZE)
      buffer_not_full.wait(l);

    buffer[end] = s;
    end = (end + 1) % BUFFER_SIZE;
    ++buffered;
    buffer_not_empty.notify_one();
  }

  string receive()
  {
    lock l(monitor);
    while (buffered == 0)
      buffer_not_empty.wait(l);

    string s = buffer[begin];
    begin = (begin + 1) % BUFFER_SIZE;
    --buffered;
    buffer_not_full.notify_one();
    return s;
  }

 private:
  int begin, end, buffered;
  string buffer[BUFFER_SIZE];
  boost::condition buffer_not_full, buffer_not_empty;
  boost::mutex monitor;
};
Thanks!