Boost logo

Boost Users :

Subject: Re: [Boost-users] [Thread] finding a good expression to wait...
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2009-09-07 23:10:23


AMDG

Julien Claassen wrote:
> Hello everyone!
> I'm trying to build a simple user-interface. It reads events from
> the keyboard using cin in one thread and then yields to a controller,
> which does some work.
> I'm doing the waiting part in the threads using condition_variables.
> The input-threads "main-function" looks something like this:
>
> *** CODE SNIPPET ***
> condition input_cond, output_cond;
> // some other code
> void main_loop(condition& in, condition& out)
> {
> char input_key;
> boost::mutex::scoped_lock lk(my_global_mutex);
> while (input_key != 'q')
> {
> while (in.timed_wait(lk,system_time(second_clock::local() +
> seconds(1)) \
> == false) // DEFINITELY NOT! good
> { }
> cin >> input_key;
> out.notify_one();
> }
> }
> *** END OF CODE ***
> The controller/output main_loop looks similar only it uses
> out.timed_wait(...) and in.notify_one(), when the crucial task is
> done. Result is, both main_loops, when passed to a thread start and
> then it's deadlocked.
> I have seen examples of the producer/consumer pattern, which worked
> with buffers and they used conditions like:
> while (buffer_full == 0)
> or similar. I only have one key, no queueing, so what to do here?
> Please any good pointer/help/example is appreciated.

You effectively need a blocking queue that holds at most one element.

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

using boost::lambda::var;

boost::condition in, out;
boost::mutex m;
char input_key;
int size;

void reader() {
    boost::unique_lock<boost::mutex> l(m);
    while(input_key != 'q') {
        in.wait(l, var(size) < 1);
        std::cin >> input_key;
        size = 1;
        out.notify_one();
    }
}

void controller() {
    boost::unique_lock<boost::mutex> l(m);
    while(input_key != 'q') {
        out.wait(l, var(size) > 0);
        std::cout << input_key << std::endl;
        size = 0;
        in.notify_one();
    }
}

int main() {
    boost::thread t1(&reader);
    boost::thread t2(&controller);
    t1.join();
    t2.join();
}

In Christ,
Steven Watanabe


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