
*From:* boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] *On Behalf Of *Steve Lorimer *Sent:* Wednesday, June 02, 2010 4:36 PM *To:* boost-users@lists.boost.org *Subject:* Re: [Boost-users] [bind] & [function] How do I store member functions with generalised arguments for later invocation?
From a quick perusal (almost bed time :) !) I can't see how I would achieve my aim, which is:
1. create the "event" (signal) which is associated with a member function "callback" (slot). Associate a thread with the event
(can I create a signal connected to a slot which is a member function?)
Yes, you can either use boost::bind() explicitly (or the Boost Lambda Library or Boost Phoenix), or I believe boost::signals2::signal::connect() will accept bind-like arguments and call boost::bind() internally.
2. in any other thread, call "post" (sig(data)) where data is a shared_ptr
3. the callback (slot) is called, running in the context of the *other* thread (the one originally associated with the "event" / (slot).
I'm trying to encapsulate a generic inter-thread messaging system where objects are passed around between threads, and associated with a member function which is designed to process said objects.
The producer creates an "event" object which is associated with the consumer_thread object, it's void consume(struct data) member function, and the thread which must process the data (consumer_thread). Now when the producer produces some data, it calls event->post(data), which queues up an object which records the class instance and it's member function which must be called with parameter "data", and a shared_ptr to data. The consumer thread wakes up, gets the top of the queue, and calls obj->mem_fun(data) --> ergo, mem_fun is called in the correct thread context, and has the argument "data" to consume.
John Dlugosz wrote:
I’m thinking of the same thing, and would reach for std::tr1::function generalized function objects to be the callback object queued between threads.
I don't quite understand your requirements, but let me take a shot. The important point that John brings out is that if you want the consumer to run code on its own thread, rather than running on the producer's thread, then I think we're talking about a queue. This would be instead of using Boost.Signals2 at all, which would call its slots immediately on the producer's thread. So you instantiate a queue and start the consumer thread waiting for items to arrive on that queue. I agree with John that it sounds like the "items" in question are std::tr1::function objects (or I'd say boost::function objects, but whatever). When you say:
The consumer thread wakes up, gets the top of the queue, and calls obj->mem_fun(data)
it's not really clear to me whether 'obj' is owned by the consumer
thread or is in the hands of the producer object. Let's consider both cases.
==== Either way:
class Data { ... };
typedef boost::shared_ptr<Data> DataPtr;
==== If 'obj' is the ConsumerClass instance:
class ConsumerClass
{
public:
...
void run();
void doSomething(DataPtr data);
void somethingElse(DataPtr data);
...
};
typedef (ConsumerClass::*ConsumerMethod)(DataPtr);
typedef boost::function