Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.
2465 Discussions

How to put a task in a queue but defer its execution?

05522541
Beginner
516 Views
Hello,

Anybody has an idea how to submit a task to a tbb scheduler, but prevent it from being executed until some further programmer-defined event (like func. call or something)?

Thanks
0 Kudos
9 Replies
Alexey-Kukanov
Employee
516 Views
You may allocate a task in advance and keep it for a while, but when you "submit", i.e. spawn() or enqueue() a task becomes available for execution and nothing can be done about it. So either you should not spawn a task until it is ready, or you make the task check its readiness inside execute() method, and recycle itself for later re-spawning. Whichever is better/more convenient, may depend on other restrictions/design forces.
0 Kudos
Dmitry_Vyukov
Valued Contributor I
516 Views
Quoting 05522541
Anybody has an idea how to submit a task to a tbb scheduler, but prevent it from being executed until some further programmer-defined event (like func. call or something)?

That's completely senseless. Why you ever need that? It's like asking for how can I call a function and not call it at the same time.

0 Kudos
Dmitry_Vyukov
Valued Contributor I
516 Views
If you submit a task to a scheduler you want it to be executed ASAP. If you do not want it to be executed ASAP do not submit it to a scheduler.
0 Kudos
Andriy_Kot
Beginner
516 Views
I have a somewhat similar problem. I am trying to do the following.
When execute method starts I first try to get a lock and if I can I do my things, release and exit.
If I cannot get a lock I want to recycle _this_/create identical task, put it back in queue and exit.

My problem is that the new/recycled task executes next rather than be put on the end of the queue.
It gets called multiple times while another task processes the region, this is exactly what I was trying to avoid. At the same time there are tasks in the queue that could process other regions.

Any idea what I do wrong? Are there any way to put the task explicitly on the end of the queue?


I could maintain my own FIFO queue and manually schedule tasks, but that is something I don't want to do for several reasons.



This is simplified code (creates identical task and spawns it):

task* RefineTask::execute ()
{
int h = region->hold.compare_and_swap(1, 0);
if (!h) { // success
processRegion(region);

// release
region->hold = 0;

} else { // region is being processed
// return this back to the queue
task &p = *parent();
RefineTask &t = *new(task::allocate_additional_child_of(p)) RefineTask(region);
p.spawn(t);
}

return NULL;
}

0 Kudos
RafSchietekat
Valued Contributor III
516 Views
If you want to poll, dedicate a tbb_thread to it. An upcoming TBB release will provide a global task queue (FIFO) in addition to the normally LIFO scheduling of locally spawned tasks (stealing is from the other side of the deque), so you could get away with this, but it still seems like abuse to me: why not choose between waiting to get the lock (if you expect short waits) or using a condition variable (if you expect long waits)?
0 Kudos
Andriy_Kot
Beginner
516 Views
I expect long waits but contentions should seldom happen. I would like to use tbb because tasks paradigm align nicely with my algorithm but I am not sure how I can use condition variable with it. Do you mean pthread_cond_t because I cannot find anything similar to condition in tbb?
0 Kudos
RafSchietekat
Valued Contributor III
516 Views

Generally speaking, don't involve TBB until you'redone waiting the way you already know.

0 Kudos
ARCH_R_Intel
Employee
516 Views

The latest open-source release of TBB has an implementation of std::condition_variable. It's in include/tbb/compat/condition_variable .

Though blocking a thread for a long time hurts the efficiency of the task paradigm. If using tasking, it might be better to use a pattern that defers execution of the task instead of blocking the thread, which of course was your original question.

Our new TBB Design Patterns document has some relevant patterns. To get it now, go to http://www.threadingbuildingblocks.org/ver.php?fid=151, and look for Design_Patterns.pdf . Chapters 8-10 may be relevant to your problem. Even though chapter 8 is called "GUI Thread", it is worth reading first because chapters 9 and 10 build upon the example there. The patterns in those chapter rely upon the new task::enqueue functionality in the latest open source release.

0 Kudos
Andriy_Kot
Beginner
516 Views
Thank you, it seems task::enqueue is a good quick solution for my case. I want a task execution postponed but can live if it is not. Glancing over patterns it looks like I might want to implement something similar to serilizer next.

Also, I cannot enqueue a task I am recycling, can I?
0 Kudos
Reply