Boost logo

Boost Users :

Subject: [Boost-users] boost::thread - Why does this code not work?
From: Henrik Berg (henrikbe_at_[hidden])
Date: 2009-06-04 08:41:46


Hi all,

I have some problems with the boost::thread library, I've been staring at
this code for a couple of days now but still have no idea what's wrong
with it. The code starts a thread, the thread waits at a barrier, and
command is transfered between the main thread and the new thread a couple
of times (using two successive calls to barrier->wait() for each
transition). This works fine most of the times, but sometimes the thread
for some reason does not start. And when the main thread then waits at the
barrier, the program obiously locks up.

Here's the code:

#include <iostream>
#include <boost/thread.hpp>
#include <boost/thread/barrier.hpp>

class ThreadObject {
public:
  boost::barrier *barrier;
  boost::thread *tacticsThread;

  ThreadObject() {
    barrier = new boost::barrier(2);
    std::cerr << "Main thread: Initiating ThreadObject\n";
    tacticsThread = new boost::thread(*this);
    std::cerr << "Main thread: ThreadObject initiated\n";
  }

  void operator()() {
    std::cerr << "Thread 2: Started\n";
    // Waiting for the main thread to release this thread:
    barrier->wait();
    std::cerr << "Thread 2: Processing.\n";

    std::cerr << "Thread 2: Waiting for the main thread...\n";
    // Release the main thread (which is waiting at the barrier):
    barrier->wait();
    // Wait at the barrier until the main thread releases this thread again:
    barrier->wait();
    std::cerr << "Thread 2: Continues.\n";

    std::cerr << "Thread 2: Completed, now releasing the main thread.\n";
    // Release the main thread (which is waiting at the barrier):
    barrier->wait();
  }
};

int main() {
  for (int i = 0; i < 100; i++) {
    std::cerr << std::endl << "Starting new test, i = " << i << std::endl;
    ThreadObject obj;
    std::cerr << "Main thread: Transferring command to Thread 2\n";

    obj.barrier->wait();
    obj.barrier->wait();

    std::cerr << "Main thread: Command returned. Transfer command back to
Thread 2 once more\n";

    obj.barrier->wait();
    obj.barrier->wait();

    std::cerr << "Main thread: completed, everything ok\n";

  }
}

In main(), a new ThreadObject is created, this will start a new thread.
Then command is transfered back and forth a few times (with pairs of
barrier->wait())). Since the code usually works fine, I've wrapped it all
in a for loop, in order to repeat it multiple times.

After a few iterations, the program locks up. The number of successful
iterations before this happens varies, here is an example of output from a
run which locked after two iterations:

Starting new test, i = 0
Main thread: Initiating ThreadObject
Main thread: ThreadObject initiated
Main thread: Transferring command to Thread 2
Thread 2: Started
Thread 2: Processing.
Thread 2: Waiting for the main thread...
Main thread: Command returned. Transfer command back to Thread 2 once more
Thread 2: Continues.
Thread 2: Completed, now releasing the main thread.
Main thread: completed, everything ok

Starting new test, i = 1
Main thread: Initiating ThreadObject
Main thread: ThreadObject initiated
Thread 2: Started
Main thread: Transferring command to Thread 2
Thread 2: Processing.
Thread 2: Waiting for the main thread...
Main thread: Command returned. Transfer command back to Thread 2 once more
Thread 2: Continues.
Thread 2: Completed, now releasing the main thread.
Main thread: completed, everything ok

Starting new test, i = 2
Main thread: Initiating ThreadObject
Main thread: ThreadObject initiated
Main thread: Transferring command to Thread 2

So, why does not the new thread start up in the last test? Is there some
problem with my code, or is there some bug in boost::thread? I'm compiling
this using gcc-3.4.4 and boost 1.39.0 under cygwin.

Thanks for any help,
Henrik


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