Boost logo

Boost :

From: Braddock Gaskill (braddock_at_[hidden])
Date: 2007-03-25 18:50:46


I don't really know where the 'future' concept came from (maybe someone does?),
but I've been looking at some old parallel programming papers, and was
surprised to find the concept of a "single-assignment variable" in a 1996 paper
by Ian Foster entitled "Compositional Parallel Programming Languages", which in
turn credited the concept to a 1982 "Data flow languages" paper by W. Ackerman.
Single assignment variables are essentially the futures concept.

Most interesting was a description of a very neat producer/consumer idiom using
these "single-assignment variables" in an academic parallel language. I
have implemented and tested this idiom in C++ using futures and
shared_ptrs below (uses my futures implementation, which is pretty generic).

It is essentially a "future stream" concept, where a linked list of futures is
constructed and then eaten by the producer and consumer respectively.

Is this new, or old hat? Either way, I'll be adding "future_stream" templates
to my implementation!

Braddock Gaskill
Dockside Vision Inc

// define my "future stream" int types...make pretty templates someday
struct stream_item;
typedef shared_ptr<stream_item> stream_item_p;
typedef future<stream_item_p> future_stream;
typedef promise<stream_item_p> promised_stream;
struct stream_item {
  stream_item(int v, promised_stream p) : value(v), next(p) {}
  int value;
  future_stream next;
};

// produces 24 int values, 0 - 23
void producer(promised_stream cur) {
  promised_stream next;
  for (int i=0; i<24; ++i) {
    next = promised_stream();
    cur.set(stream_item_p(new stream_item(i, next)));
    cur = next;
  }
  cur.set(stream_item_p()); //set a null next to terminate
}

// consumes values and sums them until the stream ends
int consumer(future_stream stream) {
  int accum=0;
  while (stream.get()) {
    accum += stream.get()->value;
    stream = stream.get()->next;
  }
  return accum;
}

void TestCase13() { //producer/consumer list of futures
  promised_stream stream;
  // launch producer
  boost::thread t(boost::bind(producer, stream));
  int accum = consumer(stream);
  BOOST_CHECK_EQUAL(accum, 276);
  t.join();
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk