Проблема при использовании ThreadPool на одноядерной системе
От: hyperlam  
Дата: 15.03.10 07:35
Оценка:
На одноядерных машинах обнаружил очень интересную проблему, которая поставила меня в тупик:
Если из нитки, работающей в ThreadPool поставить в очередь метод при помощи QueueUserWorkItem и после этого запустить бесконечное ожидание event'а, то метод никогда не будет запущен.

Проблема повторяется как при использовании managed кода (пример на C#), так и при использовании unmanaged кода (пример на delphi).

прроблема повторяется только если в системе одно ядро (например на виртуальной машине).

Вот тестовый пример на C#:

namespace TP2003_cs
{
    using System;
    using System.Threading;

    public class TP2003
    {
        static EventWaitHandle event1 = new EventWaitHandle(false, EventResetMode.ManualReset);
        static EventWaitHandle event2 = new EventWaitHandle(false, EventResetMode.ManualReset);

        static void Main(string[] args)
        {
            ThreadPool.QueueUserWorkItem(WorkItem1);
            EventWaitHandle.WaitAll(new EventWaitHandle[] { event1, event2 });
        }

        static void WorkItem1(object state)
        {
            WriteLine("WorkItem1 - begin");
            ThreadPool.QueueUserWorkItem(WorkItem2);
            WriteLine(event2.WaitOne(1000) ? "event2 - signaled" : "event2 - timeout");
            event1.Set();
            WriteLine("WorkItem1 - end");
        }

        static void WorkItem2(object state)
        {
            WriteLine("WorkItem2 - begin");
            WriteLine("event2 - set");
            event2.Set();
            WriteLine("WorkItem2 - end");
        }

        static void WriteLine(string str)
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString() + ": " + str);
        }
    }
}


выдаются следующие результаты:
На многопроцессорном компьютере:

3: WorkItem1 — begin
4: WorkItem2 — begin
4: event2 — set
4: WorkItem2 — end
3: event2 — signaled
3: WorkItem1 — end

Как видно из лога WorkItem2 запускается в новой нитке (ThreadID = 4).

Результат на однопроцессорном компьютере:

3: WorkItem1 — begin
3: event2 — timeout
3: WorkItem1 — end
3: WorkItem2 — begin
3: event2 — set
3: WorkItem2 — end

Как видно из лога WorkItem2 запускается в той же самой нитке после завершения WorkItem1.

Проверял на компьютере с физически одним процессором под Win 2003, на VirtualPC под Win XP, Win 2003, Win 7.

Подскажите, может кто-то сталкивался с данной проблемой и знает каким образом можно попытаться её обойти?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.