#c# #multithreading
#c# #многопоточность
Вопрос:
Ранее я использовал следующий код:
for (int i = 0; i < config.threads; i )
{
Thread thread = new Thread(workThread);
thread.IsBackground = true;
thread.Start();
}
public static void workThread()
{
while (true)
{
// work, 10 second
}
}
Работает нормально, но после 10-15 циклов начинает работать меньше. Затем я написал класс для создания отдельных потоков:
class ThreadsPool
{
private static int maxThreads = 0;
private static Thread[] threadsArray;
private static int activeThread = 0;
public static void Initializer(int maxThreads)
{
ThreadsPool.maxThreads = maxThreads;
for (int i = 0; i < maxThreads; i )
{
Thread thread = new Thread(Program.workThread);
thread.IsBackground = true;
thread.Start();
}
Thread threadDaemon = new Thread(Daemon);
threadDaemon.IsBackground = true;
threadDaemon.Start();
}
public static void activeThreadMinus()
{
Interlocked.Decrement(ref activeThread);
}
private static void Daemon()
{
while(true)
{
if(activeThread < maxThreads)
{
Thread thread = new Thread(Program.workThread);
thread.IsBackground = true;
thread.Start();
}
Thread.Sleep(5);
}
}
public static void workThread()
{
while (true)
{
// work 10 sec
ThreadsPool.activeThreadMinus();
}
}
}
Но проблема в том, что этот класс создает утечку памяти.
Вы понимаете, что мне приходится выполнять работу за 10 секунд, почти бесконечное количество раз, иногда количество запущенных потоков меняется. Как это можно сделать без утечек памяти и без потери производительности.
Комментарии:
1. Во-первых, что вы делаете, что вам нужно до 200 потоков? Я думаю, что это проблема дизайна. Вы всегда будете испытывать проблемы с производительностью, если у вас запущено 200 потоков. Ни один процессор не может справиться с этим быстро.
2. Мне нужно обработать изображение. Я знаю, что 200 потоков не являются невозможными.
3. Не разбивайте на 200 потоков. Разбейте на количество потоков, равное количеству ядер процессора.
4. Может быть, вам нужен пул потоков вместо этого?
5. Фреймворки TPL (
Parallel.For
) и PLINQ (enumerable.AsParallel()
) по умолчанию будут обрабатывать ваши данные, используя соответствующее количество потоков (я думаю, что это количество логических ядер * 2).
Ответ №1:
Создайте очередь и имейте столько потоков, сколько процессоров. Затем заставьте потоки считывать из очереди и обрабатывать сообщения. Не уничтожайте потоки, позвольте им выполняться бесконечно.