Subject: Re: [boost] [threadpool] new version v12
From: Anthony Williams (anthony.ajw_at_[hidden])
Date: 2008-11-03 07:19:21
"Oliver Kowalke" <k-oli_at_[hidden]> writes:
>> Here's the problem: if you take a task from the global queue or the
>> worker queue of another thread and *don't* do thread migration, then
>> you risk delaying a task and potentially deadlocking the pool.
>> Consider the sequence above: at step 5, task A is blocked, and the
>> only task it is waiting for (B) has been picked up by an idle worker
>> thread. The thread running task A now takes a new task from the global
>> queue (task N). Suppose this is a really long-running task (calculate
>> PI to 3 million digits, defrag a hard disk, etc.). Without thread
>> migration, task A cannot resume until task N is complete.
>> Obviously, if task N blocks on a future you can then reschedule task
>> A, but if it doesn't then you don't get that opportunity. If task N
>> waits for another event to be triggered from task A (e.g. a notify on
>> a condition variable) then it will never get it because task A is
>> suspended, and so the pool thread will deadlock *even when task A is
>> ready to run*.
> Wouldn't this also happen in the recursive execution of tasks (without fibers)?
Yes. I found that the safest thing to do is spawn another thread
rather than recursively executing tasks, unless I could execute the
task being waited for (in which case you only get deadlock if you
would with separate threads too). You need to pay attention to how
many threads are running, but it seems to work better.
At least with fibers you *can* migrate the task to another thread, if
your task is able to handle it.
-- Anthony Williams Author of C++ Concurrency in Action | http://www.manning.com/williams Custom Software Development | http://www.justsoftwaresolutions.co.uk Just Software Solutions Ltd, Registered in England, Company Number 5478976. Registered Office: 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK