шаблон проектирования для одновременного выполнения задачи с ограничениями - PullRequest
2 голосов
/ 18 ноября 2010

У меня есть 3 класса задач (I, D, U), которые входят в очередь, задачи одного класса должны обрабатываться по порядку.Я хочу, чтобы задачи выполнялись как можно более параллельно;однако существуют некоторые ограничения:

  • U и D не могут работать одновременно
  • U, и я не могу работать одновременно
  • I (n) требует, чтобы U (n) завершил

Q: Какой шаблон (ы) дизайна подойдет для этого класса проблем?

У меня есть два подхода, которые я рассматриваю:

Подход 1: Использовать 1 поток на задачу, каждый со своей собственной очередью.Каждый поток имеет фазу синхронизированного запуска, где он проверяет условия запуска, затем запускается, а затем фазу синхронизированной остановки.Легко видеть, что это обеспечит хороший параллелизм, но я не уверен, правильно ли он реализует мои ограничения и не блокирует тупик.

D_Thread { ...
 while (task = D_Queue.take()) {
  synchronized (State) {   // start phase
   waitForU();
   State.setRunning(D, true);
  }
  run(task);  // run phase
  synchronized (State) {   // stop phase
    State.setRunning(D, false) 
  }
 }
}

Подход 2: Альтернативноодин поток диспетчеризации управляет состоянием выполнения и планирует задачи в ThreadPool, ожидая при необходимости завершения текущих запланированных задач.

Ответы [ 2 ]

1 голос
/ 19 ноября 2010

Каркас Objective-C Foundation включает классы NSOperationQueue и NSOperation, которые удовлетворяют некоторым из этих требований.NSOperationQueue представляет очередь NSOperation с.В очереди выполняется настраиваемое максимальное количество операций одновременно.Операции имеют приоритет и набор зависимостей;все операции, от которых зависит операция, должны быть завершены до того, как очередь начнет выполнение операции.Операции запланированы для выполнения в пуле динамически измеряемых потоков.

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

0 голосов
/ 19 ноября 2010

На самом деле все оказывается проще, чем казалось: мьютекс - это в основном все, что нужно:

IThread(int k) {
 synchronized (u_mutex) {
  if (previousUSet.contains(k))) U(k);
 }
 I(k);
}

DThread(int k) {
 synchronized (u_mutex) {
  D(k);
  previousUSet.add(k);
 }
}
...