Как настроить и управлять постоянными несколькими потоками? - PullRequest
1 голос
/ 09 декабря 2010

Я имею в виду POSIX для реализации, хотя этот вопрос больше относится к архитектуре.

Я начинаю с цикла обновления, в котором нужно выполнить несколько основных задач.Я могу сгруппировать эти задания в четыре или пять основных задач, которые имеют общие требования к доступу к памяти.Моя идея разбить эти задания на их собственные потоки и сделать так, чтобы они завершили один цикл «обновления» и спали до следующего кадра.

Но как синхронизировать?Если я отсоединю четыре или пять потоков в начале каждого цикла, они будут запускаться один раз, умирать, а затем отсоединять еще 4-5 потоков на каждом проходе?Это звучит дорого.

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

Это мудрый подход?Я открыт для принятия ответов от просто идей до реализации любого рода.

РЕДАКТИРОВАТЬ: основываясь на ответах, я хотел бы добавить:

  • требуется параллелизм
  • эти рабочие потоки предназначены для работы на очень короткихдлительности <250 мс </li>
  • работа, выполняемая каждым потоком, всегда будет одинаковой
  • Я рассматриваю 4-5 потоков, 20 - жесткий предел.

Ответы [ 4 ]

2 голосов
/ 10 декабря 2010

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

И наоборот, если у вас есть очень короткие задачи (например, менее 10-100 мс или около того), вы определенно начнете замечать стоимость создания и уничтожения большого количества потоков. В этом случае, да, вы должны создать потоки только один раз и дать им спать, пока не придет работа для них. Для этого вам понадобится какая-то условная переменная (например, pthread_cond_t): поток ожидает условную переменную, а когда приходит работа, вы сигнализируете условную переменную.

1 голос
/ 10 декабря 2010

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

Вам потребуются некоторые объекты синхронизации: «семафор начала кадра», «семафор конца кадра» и «событие конца кадра».Если у вас есть n независимых задач в каждом кадре, запустите n потоков с циклами, которые выглядят следующим образом (псевдокод):

while true:
  wait on "start of frame semaphore"
  <do work>
  enter lock
  decrement "worker count"
  if "worker count" = 0 then set "end of frame event"
  release lock
  wait on "end of frame semaphore"

Затем можно запустить поток контроллера:

while true:
  set "worker count" to n
  increment "start of frame semaphore" by n
  wait on "end of frame event"   
  increment "end of frame semaphore" by n

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

1 голос
/ 09 декабря 2010

Лучше всего использовать очередь задач.

Очереди задач можно рассматривать как потоки, ожидающие отправки задания им.Если отправляется много сообщений одновременно, они выполняются в порядке FIFO.

Таким образом, вы поддерживаете 4-5 потоков, и каждый из них выполняет задание, которое вы им кормите, без необходимости отсоединять новый потоккаждая работа.

Единственная проблема заключается в том, что я не знаю многих реализаций очередей задач в C. У Apple есть Grand Central Dispatch, которая делает именно это;У FreeBSD также есть реализация.Кроме тех, я не знаю другого.(Я выглядел не очень усердно, хотя.)

0 голосов
/ 10 декабря 2010

Ваша идея известна как пул потоков.Их можно найти в WinAPI, Intel TBB и Visual Studio ConcRT. Я мало знаю о POSIX и поэтому не могу вам помочь, но они представляют собой отличную структуру со многими желаемыми свойствами, такими как отличное масштабирование, если опубликованная работа можетбыть разделенным.

Тем не менее, я бы не стал упрощать время, затрачиваемое на работу.Если у вас есть пять задач и у вас проблемы с производительностью, настолько отчаянные, что ключом являются несколько потоков, то создание потоков почти наверняка незначительная проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...