Нужна помощь в понимании .net ThreadPool

Я пытаюсь понять, что делает 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), пока они все не закончатся? Или я не понимаю, что он делает на самом деле.


person Meredith    schedule 21.02.2011    source источник
comment
Ну, вы пробовали запустить его и посмотреть, что происходит?   -  person Lasse V. Karlsen    schedule 22.02.2011
comment
Разве это не очень хорошо объясняет, что должен делать SetMinThreads. msdn.microsoft.com/en-us/library/ ... в конце дня количество фактически развернутых потоков будет зависеть от доступных системных ресурсов, которые могут меняться при каждом запуске.   -  person James Gaunt    schedule 22.02.2011


Ответы (4)


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

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

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

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

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

person Lasse V. Karlsen    schedule 21.02.2011

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

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

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

person Joe    schedule 21.02.2011
comment
Это отличная ссылка и отличный ресурс о том, что происходит с потоками. Я совсем забыл упомянуть об этом. Хороший! +1 - person David Hoerster; 22.02.2011
comment
я читал и перечитывал это последние 3 дня, пытаясь реализовать это! - person Joe; 22.02.2011
comment
Мы создали многопоточный сервис для обработки очень специфических запросов, и его объяснение шаблона ожидания и импульса было неоценимым. albahari.com/threading/part4.aspx#_How_to_Use_Wait_and_Pulse - person David Hoerster; 22.02.2011
comment
Для нас на нашу службу опросов повлияла огромная фоновая работа, которая выполнялась между периодическими опросами. Я даже не добрался до главы 4, просто использовал шаблон EAP в фоновых рабочих процессах (.net 3.5) и блокировках. Я еще недостаточно уверен, чтобы сделать слишком много на этом этапе! Но да, краткие и простые объяснения. Я действительно начал понимать многопоточность после нескольких попыток. - person Joe; 22.02.2011

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

Когда спрос низкий, фактическое количество потоков пула потоков может упасть ниже минимальных значений.

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

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

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

person David Hoerster    schedule 21.02.2011

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

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

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

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

person KeithS    schedule 21.02.2011