Я пытаюсь понять, что делает 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), пока они все не закончатся? Или я не понимаю, что он делает на самом деле.
Ну, вы пробовали запустить его и посмотреть, что происходит? Lasse V. Karlsen 22.02.2011
Разве это не очень хорошо объясняет, что должен делать SetMinThreads. msdn.microsoft.com/en-us/library/ ... в конце дня количество фактически развернутых потоков будет зависеть от доступных системных ресурсов, которые могут меняться при каждом запуске. James Gaunt 22.02.2011
Установив минимальное число потоков, единственное, что вы просите от среды выполнения .NET, - это выделить как минимум 2 потока для пула потоков. Вы не просите его ограничить себя только двумя.
Таким образом, нет никакой гарантии, сколько потоков конкретно ваша программа будет использовать для этого. Это зависит от вашей системы и многих других факторов.
Простой тест, который я сделал (незначительное изменение в вашей программе, чтобы просто отслеживать одновременные потоки, входящие в вызов сна), достиг максимума 4 в одном запуске, 3 в другом, 7 в другом, 10 в другом и т. д.
Вам действительно не нужно менять размер пула потоков.
Что вы пытаетесь достичь?
Ответ 2 · рейтинг 3 · Joe
Если у вас есть немного времени, я бы очень рекомендовал это прочитать:
Это отличное чтение, которое закладывает основу и проходит путь от базовых потоков до параллельного программирования. Я бы рекомендовал вам иметь общее представление о первых двух главах, прежде чем пытаться модифицировать код пула потоков! :)
Когда спрос низкий, фактическое количество потоков пула потоков может упасть ниже минимальных значений.
Таким образом, указанное вами значение не гарантирует, что 2 рабочих потока будут работать с элементами очереди. Это может быть 1 рабочий поток (поскольку вы ставите их в очередь в цикле, он может завершиться до того, как в очередь будет поставлен следующий), или он может использовать больше в зависимости от системных ресурсов и объема работы, которую необходимо выполнить. .
Справочная информация. Обычный метод, с помощью которого пул потоков .NET управляет потоками, может быть громоздким. Он хорошо работает для ограничения проблем, вызванных конфликтом ресурсов, но делает это за счет того, насколько быстро создаются потоки. Чтобы повысить производительность обработки рабочих потоков с помощью пула потоков, разработчики предусмотрели механизм, который позволяет создавать определенное небольшое количество потоков без прохождения процесса очереди.
SetMinThreads() указывает количество потоков, которые должны быть просто созданы "по запросу", то есть просто запущены без каких-либо проверок текущего количества потоков или постановки в очередь для медленного дросселирования.
Что произойдет, так это то, что фреймворк немедленно создаст первые два потока, как если бы вы вручную настроили их и отключили их с помощью Thread.Start. Кроме того, до текущего значения MaxThreads фреймворк начнет ставить в очередь запросы на рабочие потоки и запускать их с заданным интервалом (по умолчанию 250 мс, думаю, это тоже можно настроить), чтобы избежать конфликта ресурсов. Причина этого в том, что если вы представляете зацикленное поведение запуска потока, который обращается к ресурсу, выполняет некоторые вычисления, а затем записывает результат куда-то еще, вы можете увидеть, как 5 потоков, запускающихся почти одновременно, вызовут тупик при попытке получить к этому первому ресурсу. При достижении порога MaxThreads очередь останавливается; новые потоки не создаются, пока не завершится один.
Таким образом, по характеру вашего кода будет запланировано 50 отдельных рабочих задач, но не все 50 будут выполняться одновременно; среда выполнения позволит запустить два сразу, затем подождите 250 мс или пока не закончится один, прежде чем запустить следующий. Поскольку потоки будут выполняться и завершаться менее чем за 250 мс, вы вряд ли увидите одновременное выполнение более двух рабочих потоков; ожидание перед созданием этого третьего никогда не произойдет, потому что "неограниченный" рабочий поток освобождается первым, а тот, который ожидал, запускается до истечения времени его ожидания, затем часы сбрасываются со следующим.