4

Closed

Problem when launching several jobs at the same time

description

I changed the TestSmartThreadPool demo to do this :

for (int i = 0; i < 20; i++)
{
workItemCallback = new WorkItemCallback(this.DoWork);
workItemsGroup.QueueWorkItem(workItemCallback);
workItemsGenerated++;
}

Some times, the ThreadPool creates only 19 threads instead of 20. Even if MaxThreads is set to 25.

I suppose the SmartThreadPool follows a scenario like this :
  • Initially : queue and ThreadPool are empty.
  • Main thread : Enqueue Job #1 ( so WaitingCallbacks is set to 1 and a new thread #1 is created)
  • Thread #1 : Dequeue Job #1 ( so WaitingCallbacks is set to 0)
  • Main thread : Enqueue Job #2 ( WaitingCallbacks is incremented but InUseThreads is still 0, so no thread is created here )
  • Thread #1 : Start Job #1 (InUseThreads is set to 1)
    ... and so on.
I worked around by adding a Thread.Sleep(10) between each job creation but it's not optimized ...

file attachments

Closed Aug 22, 2012 at 6:21 AM by
Updated as proposed in STP 2.2.2

comments

etichy wrote Jun 25, 2012 at 12:32 PM

Hi. I have similar problem and it causes me deadlock, because I work with WorkingGroups where I count on concurrency, but SmartThreadPool doesn't create enough threads. So instead of create new thread for each group, it stuck with 1 thread.
I explored source code, and it's typical rice condition.

In method Enqueue we assign item work queue and after that we check whether we need to create add thread. It's done by condition (WaitingItems + InUseItems) > workerThreads.
Unfortunately Dequeue item from queue and Increase InUseItems are not in critical section. So it happens sometime that it dequeues item, but it wasn't able to increase counter for InUseItems.


I vote for fixing this issue in next version.

etichy wrote Jun 25, 2012 at 1:53 PM

Solution is to change condition in function Enqueue

from
if ((InUseThreads + WaitingCallbacks) > _workerThreads.Count)
to
if ( _currentWorkItemsCount > _workerThreads.Count)