2011-02-07 1 views
3

Я собираюсь запустить проект C# .NET 4.0, который создает планировщик заданий.Планировщик заданий с использованием MultiThreading с приоритетом

  1. Срок действия задания не установлен и потенциально долго работает, вплоть до дней.
  2. Работа имеет 3 приоритета: простой, нормальный, критический; от самого низкого до самого высокого.
  3. Новые задания (ы) постоянно создаются.
  4. Более новая работа с более высоким приоритетом должна иметь приоритет над более низким приоритетом, даже если старое задание создано в течение длительного времени.
  5. Каждая работа будет обрабатываться одной длинной рабочей нитью.
  6. Работа повторного входа. Состояние задания сохраняется в базе данных, поэтому можно приостановить работу или прекратить работу в любой момент.

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

Моя проблема заключается в том, чтобы гарантировать, что высокоприоритетная цепочка сначала войдет в семафор, когда семафор вызывает метод release(). Выполнимо?

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

Для этих двух проблем семафор правилен? Если нет, что вы предлагаете?

+0

Почему бы не использовать Quartz.Net? –

+1

Ну, моя схема планирования основана исключительно на приоритете, и определенная работа должна быть остановлена ​​на основе нового прибытия работы. Может ли quartz.net помочь мне здесь? – nobody

+1

Не уверен в прекращении работы, но Quartz.Net имеет приоритетную обработку. –

ответ

4

Ну, я бы наклонился к чему-то вроде следующего ...

первых, начните все темы вы хотите:

for(int i=0; i < Environment.ProcessorCount; i++) 
{ 
    Thread t = new Thread(RunWork); 
    // setup thread 
    t.Start(); 
    threads.Add(t); 
} 

Вам потребуется интерфейс для описания приоритет задачи

interface ITask { 
    PrioirtyType Prioirty { get; } 
    bool Complete { get; } 
    void PerformOneUnitOfWork(); 
} 

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

class MyQueue<TJob> where TJob : ITask 
{ 
    Queue<TJob> high, med, low; 
    bool GetNextJob(ref TJob work) 
    { 
     if(work.Priority == PriorityType.High && !work.Complete) 
      return true; 
     lock(this) 
     { 
      if(high.Count > 0) 
      { 
       Enqueue(work);//requeue to pick back up later 
       work = high.Dequeue(); 
       return true; 
      } 
      if(work.Priority == PriorityType.Med && !work.Complete) 
       return true; 
      if(med.Count > 0) 
      { 
       Enqueue(work);//requeue to pick back up later 
       work = med.Dequeue(); 
       return true; 
      } 
      if(!work.Complete) 
       return true; 
      if(low.Count > 0) 
      { 
       work = low.Dequeue(); 
       return true; 
      } 
      work = null; 
      return false; 
     } 

    void Enqueue(TJob work) 
    { 
     if(work.Complete) return; 
     lock(this) 
     { 
      else if(work.Priority == PriorityType.High) high.Enqueue(work); 
      else if(work.Priority == PriorityType.Med) med.Enqueue(work); 
      else low.Enqueue(work); 
     } 
    } 
} 

И наконец создать рабочий поток что-то вроде следующий:

public void RunWork() 
{ 
    ITask job; 
    while(!_shutdown.WaitOne(0)) 
    { 
     if(queue.GetNextJob(ref job)) 
      job.PerformOneUnitOfWork(); 
     else 
      WaitHandle.WaitAny(new WaitHandle[] { _shutdown, queue.WorkReadyHandle }); 
    } 
} 
+0

Это великолепно, так или иначе я чувствую, что это может быть то, что я ищу. Можете ли вы сказать мне, какой тип данных _shutdown? – nobody

+0

Я не вижу, что WorkReadyHandle определен где-нибудь в классе MyQueue. Я что-то пропустил? Я новичок в C# в целом. – nobody

+0

_shutdown - это либо «Thread», либо «ManualResetEvent» - скорее всего, Thread. Я бы по-прежнему предпочитал TPL над ручным управлением потоками, особенно. с .Net 4. – IAbstract

3

Для этих двух проблем семафор правильный подход? Если нет, что вы предлагаете?

На самом деле это зависит. Зачастую лучше иметь более одного задания на поток, поскольку многие (особенно длительные) рабочие элементы будут тратить свое время, ожидая чего-то другого, кроме процессора. Например, если вы выполняете работу, когда работаете с WCF-сервисами или другими связанными с этим проблемами, вы можете потратить много времени на блокировку и простоя.

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

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

Это, как говорится, я бы, вероятно, не использовал семафор для этого. Хотя он будет работать, один счетчик (управляемый через Interlocked.Increment/Decrement) и ManualResetEvent будет работать так же хорошо, и будет намного легче.

+0

Использование семафора, по-моему, сигнализирует реализацию параллельной библиотеки задач. Разве TPL и семафор в значительной степени не работают? TPL дает вам большой контроль. Высокоприоритетное задание будет выставлено в очередь (например, индекс 0), отбрасывая низкоприоритетные задания. В этот момент TPL позволит вам приостановить работу с наименьшим приоритетом ... ??? Или я что-то недопонимаю ... – IAbstract

+0

@IAbstract: TPL может быть очень полезен, хотя у него нет ничего встроенного для «паузы», а использование семафонов действительно отделено от TPL ... –

+0

Правильно, есть много деталей реализации не учтено ... и я не был уверен, действительно ли была пауза в TPL или нет. Тем не менее, я уверен, что можно сохранить состояние работы, по сути дела, приостанавливая задачу. :) – IAbstract

 Смежные вопросы

  • Нет связанных вопросов^_^