Создавайте новые темы или получайте больше работы для тем

У меня есть программа, которую я создаю (на С#), и я вижу два подхода.

1) Диспетчер заданий, который ожидает завершения любого количества потоков X, по завершении он получает следующий кусок работы, создает новый поток и отдает ему этот кусок.

or

2) Мы создаем X потоков для запуска, даем каждому из них часть работы, и когда поток завершает работу, он запрашивает у менеджера заданий дополнительную работу. Если больше нет работы, он спит, а затем снова спрашивает, при этом сон становится все длиннее.

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

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


person Community    schedule 31.03.2009    source источник
comment
чтобы прояснить подход 1, он ожидает завершения потока, а затем создает новый поток и дает этому потоку дополнительную работу, если есть еще работа, которую нужно выполнить.   -  person    schedule 31.03.2009
comment
Учитывая это, используйте второй подход. Однако вместо процедуры сна-проверки-сна поток запрашивает рабочий элемент в конце. Если его нет, пусть он спит на неопределенный срок. Затем в вашем координаторе найдите спящие потоки и подайте сигнал одному из них, чтобы проснуться.   -  person Adam Robinson    schedule 31.03.2009


Ответы (4)


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

person Adam Robinson    schedule 31.03.2009

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

Скорее, у вас должен быть объединенный набор потоков, как во втором варианте, но они используют WaitHandles для ожидания работы и используют шаблон производителя/потребителя. По сути, когда производитель указывает, что есть работа, он отправляет сигнал потребителю (будет менеджер, который определит, какой поток получит работу, а затем сигнализирует этому потоку), который проснется и начнет работать.

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

person casperOne    schedule 31.03.2009
comment
Проблема с PTL заключается в том, что он максимально загружает ЦП, и мы больше привязаны к БД, поэтому нам нужно более тщательно управлять количеством thr. Шаблон P/C — это вариант 1, за исключением того, что вместо создания нового thr после завершения потока thr переходит в спящий режим, а p ищет ожидающий thr и отправляет ему дополнительную работу? - person ; 31.03.2009

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

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

person Douglas Leeder    schedule 31.03.2009

Вместо создания собственного решения вам следует взглянуть на класс ThreadPool в среде .NET. Вы можете использовать метод QueueUserWorkItem. Он должен делать именно то, чего вы хотите достичь.

person EFrank    schedule 31.03.2009
comment
@EFrank: Если работа длится долго, то это не лучшая идея. - person casperOne; 31.03.2009
comment
@EFrank (+1 к casperOne): класс ThreadPool использует системные потоки и предназначен для операций с коротким жизненным циклом (и довольно нечастым использованием). Если вы более требовательны, вы должны создавать свои собственные потоки. - person Adam Robinson; 31.03.2009