简体   繁体   中英

How to implement message passing for a single message?

I have implemented a job/task system. You can create a function<void, void> and place it on a thread local queue, before that I wrap the function in a Fiber.

Now that works perfectly fine at the moment but it would be quite useless if I can not return values. function<T, void>

That means I would need a way to do message passing. I implemented it this way:

I have a Cell<T> which can store a variable and has an atomic counter. I take a function<T, void> , wrap in in a closure. Once the function has been executed it will write into the cell and decrement the counter. Now when I create the closure I have to pointer to a cell, one is inside the closure and one is outside.

The closure is of type function<void, void> and I also wrap it in a fiber and put it in a thread local queue.

Now outside of the task system I can check that cell if the counter has decremented to 0. If it has I know the task must have finished, otherwise I have to wait. I only wait in the main thread outside of the task system. Inside the task system I can just reschedule.

I have not done any multihreaded programming before and this was the only way that I could imagine to implement "message passing".

I am pretty sure that something like my Cell has already been invented, but I am not sure what the general name for it is.

Is this a common way to implement message passing? By that I mean "Wrapping a cell inside a closure and wait for completion".

What is the correct name of my Cell and are there any implementations of it available online?

There is a way to pass one message, and it's called "future". A "future" is an object that will hold a value in (near) future (hence the name), and you can poll it (or wait) in order to get the value. In C++11, it exists under the form of std::future . The emitter side of a future is a promise .

For your case:

  1. someone gives a std::function<T()> to be scheduled for execution
  2. you wrap this function in a fiber. While doing this, you should actually wrap it in a std::function<void()> first:

     std::promise<T> promise; std::future<T> future = promise.get_future(); std::function<void()> wrapped = [f, p = std::move(promise)]() { p.set_value(f()); }; // do stuff with 'wrapped' return future; 
  3. With the returned future you can either wait for a value (blocking call) or poll it to know when the value is done.

Bonus: you can also create a std::future<void> , in which case you can still call get() or still poll it; it will act a signal for the completion of the function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM