Showing results for 
Search instead for 
Did you mean: 

Blocking (waiting) version of try_put()?

Hello, and thank you all for TBB; it is a wonderful library. I am already using "parallel_do" to great effect in one application.

Now I am considering how to map a different application onto the TBB model, and flow graphs appear to be very close what I want.

However, my "messages" are large, so I need to limit how many of them are in flight at a time. I have read the "Flow Graph Tips for Limiting Resource Consumption" chapter -- in particular, the "Create a Token-Based System" section -- but the pull model it requires is very unnatural in my case.

The problem is that my message source really wants a push model. The actual generation of messages is deep inside a nested set of member function calls on various objects. Capturing all of that state in some kind of closure/continuation so that I can spit out the next message on-demand would require a major restructuring (and, in my opinion, uglification) of the code.

Is there a variant of try_put() that simply waits until there is room for the next message? Of course I do not want the underlying thread to block; I want it to go off processing other tasks like wait_for_all() etc.

Or is there some straightforward way to achieve a similar effect (e.g. a simple semaphore primitive that knows how to process other tasks while waiting)?


0 Kudos
2 Replies

Hi Patrick,

You may want to consider source_node. It is designed to stop execution when try_put cannot accept the message. When the resource becomes available and try_put can accept the message, the body of source_node is called again. I.e. you can connect the output of the source_node with the input of the limiter_node. However, it might require significant code refactoring.



Hi, Alex. Thank you for your reply.

The manual section I mentioned ("Create a Token-based System") uses source_node for its example. Unfortunately, in my case, the generation of work is a complex process... It is not at all a pull model ("give me the next thing to work on"); it is a push model ("do various nested calls that generate things incrementally"). So the refactoring would be enormous, and the result would be much harder to understand and to get right, in my opinion.

Internally, TBB must have some primitives of the form "wait for something, but have this thread work on other tasks in the meantime". Are none of those available directly to client code? For example, does concurrent_bounded_queue actually block the thread, or does it find another task to run when it needs to wait?

If no such primitives are available, this seems like it would make a good addition to the library, unless I am missing something fundamental...