Boost logo

Boost :

Subject: Re: [boost] [threadpool] new version v12
From: Anthony Williams (anthony.ajw_at_[hidden])
Date: 2008-11-03 09:19:17


"vicente.botet" <vicente.botet_at_[hidden]> writes:

> ----- Original Message -----
> From: "Anthony Williams" <anthony.ajw_at_[hidden]>
> To: <boost_at_[hidden]>
> Sent: Monday, November 03, 2008 1:19 PM
> Subject: Re: [boost] [threadpool] new version v12
>
>
>>
>> "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.
>
> This is interesting feature to combine with the disable work stealing,
> the thread_pool will have no more that n running working threads,
> others can be blocked, and others are frozen. The working thread
> scheduler will spawn another thread or unfreeze a frozen thread before
> blocking. These threads could be added to the thread pool only when
> some thread is blocked and no frozen thread exists, so at the end
> there are always no more than the initial number of threads
> running. The working thread scheduler can put itself on the frozen
> list when there are already the initial number of threads running.

Yes.

>> At least with fibers you *can* migrate the task to another thread, if
>> your task is able to handle it.
>
> I don't see any major issue to migrate tasks when the blocking
> function get() calls recursivelly to the working thread scheduler. Is
> there one?

If the task migrates across threads its ID changes, and thread locals
change.

Anthony

-- 
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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk