Нужна помощь в понимании .net ThreadPool - PullRequest
3 голосов
/ 22 февраля 2011

Я пытаюсь понять, что делает ThreadPool, у меня есть пример .NET:

class Program
{
    static void Main()
    {
        int c = 2;

        // Use AutoResetEvent for thread management

        AutoResetEvent[] arr = new AutoResetEvent[50];

        for (int i = 0; i < arr.Length; ++i)
        {
            arr[i] = new AutoResetEvent(false);
        }

        // Set the number of minimum threads
        ThreadPool.SetMinThreads(c, 4);

        // Enqueue 50 work items that run the code in this delegate function
        for (int i = 0; i < arr.Length; i++)
        {
            ThreadPool.QueueUserWorkItem(delegate(object o)
            {
                Thread.Sleep(100);
                arr[(int)o].Set(); // Signals completion

            }, i);
        }

        // Wait for all tasks to complete
        WaitHandle.WaitAll(arr);
    }
}

Выполняет ли это 50 «заданий» в группах по 2 (int c), пока все они не закончатся? Или я не понимаю, что он на самом деле делает.

Ответы [ 4 ]

3 голосов
/ 22 февраля 2011

Если у вас есть немного времени, я очень рекомендую это прочитать:

http://www.albahari.com/threading/

Это отличное чтение, которое лежит в основе и работает от базового многопоточности до параллельного программирования. Я бы порекомендовал вам ознакомиться с первыми двумя главами, прежде чем пытаться изменить код пула потоков! :)

1 голос
/ 22 февраля 2011

Устанавливая количество потоков минимум , единственное, что вы просите среду выполнения .NET, - это выделите как минимум 2 потока для пула потоков.Вы не просите, чтобы ограничивало само по себе только 2.

Таким образом, нет гарантии того, сколько потоков, в частности, ваша программа будет использовать для этого.Это зависит от вашей системы и множества других факторов.

Я сделал простой тест (незначительное изменение в вашей программе, чтобы просто отслеживать одновременные входящие потоки в спящем вызове) с максимальным значением 4 за один проход, 3в другом, 7 в другом, 10 в другом и т. д.

Вам действительно не нужно менять размер пула потоков.

Чего вы пытаетесь достичь?

0 голосов
/ 22 февраля 2011

Справочная информация. Обычный метод управления потоками в .NET может быть громоздким. Он хорошо работает для ограничения проблем, вызванных конфликтом ресурсов, но делает это за счет того, насколько быстро создаются потоки. Чтобы повысить производительность рабочих потоков с помощью пула потоков, разработчики предусмотрели механизм, который позволяет создавать определенное небольшое количество потоков без прохождения процесса очереди.

SetMinThreads () указывает количество потоков, которые должны быть просто созданы «по требованию», то есть просто запущены без каких-либо проверок текущего количества потоков или в очереди для медленного увеличения скорости.

Что произойдет, это то, что фреймворк сразу же создаст первые два потока, как если бы вы вручную настраивали их и запускали их с помощью Thread.Start. Кроме того, вплоть до текущего значения MaxThreads, инфраструктура начнет ставить в очередь запросы для рабочих потоков и запускать их через определенный интервал (по умолчанию 250 мс, я полагаю, это также можно настроить), чтобы избежать конфликта ресурсов. Причина этого заключается в том, что если вы представляете себе зацикленное поведение запуска потока, который обращается к ресурсу, выполняет некоторые вычисления, а затем записывает результат где-то еще, вы можете увидеть, как 5 потоков, запускающихся почти одновременно, могут вызвать переполнение, пытаясь получить на этот первый ресурс. На пороге MaxThreads очередь останавливается; новые потоки не создаются, пока не закончится.

Таким образом, по природе вашего кода будет запланировано 50 отдельных рабочих задач, но не все 50 будут выполняться одновременно; среда выполнения позволяет двум запускаться немедленно, затем подождать 250 мс или пока один не закончится, прежде чем начать следующий. Поскольку потоки будут выполняться и завершаться менее чем за 250 мс, вы вряд ли увидите более двух рабочих потоков, выполняющихся одновременно; ожидание перед созданием этого третьего никогда не произойдет, потому что «неограниченный» рабочий поток сначала освобождается, а ожидающий запускается до истечения времени ожидания, а затем часы сбрасываются со следующим.

0 голосов
/ 22 февраля 2011

Из документации MSDN по SetMinThreads :

При низком требовании фактическое число потоков пула потоков может упасть ниже минимальных значений.

Таким образом, указанное вами значение не гарантирует, что 2 рабочих потока будут работать с элементами в очереди.Это может быть 1 рабочий поток (поскольку вы ставите их в очередь в цикле, он может закончиться до того, как следующий будет поставлен в очередь), или он может использовать больше в зависимости от системных ресурсов и объема работы, который необходимо выполнить..

Если вы действительно хотите увидеть, что происходит, воспользуйтесь инструментом, например Process Monitor .Вы можете отслеживать процесс создания потоков и отслеживать, когда они создаются, уничтожаются и т. Д. Это действительно поможет вам понять, что делает ваше приложение (и базовая структура).

Надеюсь, это поможет.

...