Thursday 15 January 2015

c++ - Proper way to cancel all waiting pushes or pops on tbb::concurrent_bounded_queue? -



c++ - Proper way to cancel all waiting pushes or pops on tbb::concurrent_bounded_queue? -

i using tbb::concurrent_bounded_queue communicate in buffered fashion between n producer/consumer threads.

like so:

//which has been set max capacity tbb::concurrent_bounded_queue<myitemtype> g_queue; threada() { while(running_a) { myitemtype outitem; //do stuff, resulting in filling outitem ... g_queue.push(outitem); } } threadb() { while(running_b) { myitemtype initem; g_queue.pop(initem); //do stuff contents of initem } }

the illustration showed has 1 producer , 1 consumer, in reality there can many of both. @ user's request processing should cease possible.

so if thread has pushed few items, b had not consumed, want next phone call b's pop homecoming somehow indicating queue closed can break loop. items on queue not serviced yet can discarded.

if thread waiting on push, want homecoming immediately, perhaps indicating queue closed business.

i read way of potentially doing force special item (stop item, indicator of cease , desist) on queue, when item popped can know things stopping. issue it's fifo queue, , items ahead of stop item need popped before can stop item. want avoid.

i see there q.abort method, cause waiting force or pops homecoming throwing exception (works if set tbb preprocessor define tbb_use_exceptions). didn't think having turn on exceptions of tbb proper way of doing this?

i thought clear queue before adding stop item, theoretically producer can come in between current consumers q.clear() , q.push(stopitem), , force non-stopitem, not want. since have wait non-stopitem processed before can pushed stopitem.

what proper way of handling this? had own queue implementation had close signal cause pops , pushes homecoming (not fill in reference item parameter, homecoming code function all) value code indicate queue closed. not sure how have similar capability tbb's concurrent bounded queue.

any suggestions?

thanks, -ryan

if understand correctly, inquire how terminate producer&consumer @ random moment without processing remaining elements. if so, need separate notification mechanism, e.g. flag:

tbb::atomic<bool> is_finished = false;

then, can read flag in loops in order terminate them if not blocked:

threada() { while(running_a && !is_finished) { myitemtype outitem; //do stuff, resulting in filling outitem ... seek { g_queue.push(outitem); } catch(...) {} } } threadb() { while(running_b && !is_finished) { myitemtype initem; seek { g_queue.pop(initem); } catch(...) {} if(is_finished) // check before processing break; //do stuff contents of initem } } terminate() { is_finished = true; g_queue.abort(); }

if thread blocked, abort() looks fine way unless needs done fast , repeatedly. tbb_use_exceptions turned on default in tbb binaries, so, don't pay in tbb scheduler , conurrent_bounded_queue internals. , tbb_use_exceptions turned on default in tbb headers if application compiled enabled exceptions (often true). pay try/catch block around push&pop.

there alternatives exception. straightforward 1 unblock threads popping items unblock producers , pushing dummy item unblock consumers. e.g.:

terminate() { is_finished = true; myitemtype dummyitem; while(g_queue.size() < 0) // consumers blocked g_queue.try_push(dummyitem); while(g_queue.size() >= g_queue.capacity() ) // producers blocked g_queue.try_pop(dummyitem); }

c++ multithreading tbb

No comments:

Post a Comment