Boost logo

Boost :

From: Niall Kelly (ngktab_at_[hidden])
Date: 2002-07-10 23:06:00


I am working on a project in which we would like to be
able to run the slots that are connected to a signal
in a thread pool. (I am using Boost 1.28.0, the most
recent Boost.Signals from the CVS repository and David
Moore's thread pool implementation from Boost Files on

We thought that using a custom Combiner for the signal
would be a useful place from which to pass the "slot
work" on to the thread pool. Essentially, the combiner
passes the slot_call_iterator to the thread pool as

custom_combiner::operator()(InputIterator first,
                            InputIterator last) const
  while (first != last)
    tp.add(job_adapter(doJob, first));
  // tp.join() - see below for discussion



void doJob(sc_iter iter)


The job_adapter used by the combiner is similar to
that in David Moore's thread-pool example usage but
with int replaced by sc_iter.

(1) Why join _was_ used

With the call to join above uncommented, the test
program "succeeds" i.e. each of the connected slots
runs in a thread allocated by the thread pool. (The
slots used for this test simply sleep for varying
amounts of time (related to the double argument in the
signal signature) and display the times at which they
start and finish).

The reason we needed the join in order to "succeed" is
that without it, the combiner's operator() returns
before the various doJob threads have used the sc_iter
parameter. As soon as custom_combiner::operator()
returns, these iterators are invalid (presumably the
container of slots over which they iterate no longer
exists). With join uncommented, the combiner only
returns after the doJob threads have completed.

(2) Why the use of join is not a real solution

The problem, of course is that we do not want to have
to join (the thread pool is no longer usable AND the
fact that we join means that the signal invocation
effectively blocks until each slot (running in a
thread-pool thread) completes).

The original concept was that by running the slots in
a thread-pool, the signal invocation would just kick
off the worker-threads to do the "slot work" and
immediately return.

(3) Next Step?

I don't fully understand how the slot_call_iterator
works. However, it is obvious that the iterators
passed to doJob are not valid after
custom_combiner::operator() has returned. Would it be
possible (within the combiner) to obtain an underlying
boost::function for each slot-call from the
slot_call_iterators? Perhaps this function object
could be passed to the worker-threads.

Any other suggestions would be greatly appreciated.

Niall. -
- Find yourself a bargain!

Boost list run by bdawes at, gregod at, cpdaniel at, john at