2016-11-30 10 views
1

Я реализовал 5-этапный симулятор конвейера команд процессора в Java с использованием многопоточности.Управление потоками Java в симуляторе конвейера команд процессора

Каждый этап - это поток, который выполняет в основном ниже 3 функций, также есть очередь (емкости 1) между каждыми двумя этапами.

  1. Получать с предыдущего этапа.
  2. Процесс выполняет свою основную ответственность.
  3. Перейти к следующей стадии.
@Override 
    public void run() { 
     while (!(latchQueue.isEmpty())) { 
      fetch(); 
      process(); 
      forward(); 
     } 
    } 

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

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

Как это сделать? мне нужно приостановить поток, если указанные тактовые циклы уже достигнуты? Если да, то как я могу изящно обрабатывать приостановление/остановку потоков? Пожалуйста, помогите мне в выборе наилучшего подхода. Заранее спасибо

+1

Является ли 'latchQueue' очередью между этой стадией и следующей? Вы должны показать больше кода, чтобы понять. Если 'latchQueue' временно становится пустым, не будет ли поток неправильно завершен? То есть, если второй этап обрабатывает все, отправляемые ему, не будет ли условие 'while' становиться ложным, что приведет к завершению метода run? – BeeOnRope

+0

Я бы просто изменил условие цикла на «true» и использовал явный объект «stop» для завершения очереди (тогда как пустой мне кажется неправильным). Тогда вы можете просто позволить очереди голодать, чтобы приостановить ее. – Durandal

ответ

0

Будет ли следующая работа?

Поделиться следующим классом CyclesCounter между всеми вашими темами, представляющими этапы. Он имеет метод tryReserve, получая true от него, поскольку поток имеет достаточно «тактовых циклов» для его следующего прогона. Получение false означает, что осталось недостаточно циклов. Класс является потокобезопасным.

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

class CyclesManager { 

    private final AtomicInteger cycles; 

    CyclesManager(int initialTotalCycles) { 
     if (initialTotalCycles < 0) 
      throw new IllegalArgumentException("Negative initial cycles: " + initialTotalCycles); 

     cycles = new AtomicInteger(initialTotalCycles); 
    } 

    /** 
    * Tries to reserve given nr of cycles from available total nr of cycles. Total nr is decreased accordingly. 
    * Method is thread-safe: total nr of is consistent if called from several threads concurrently. 
    * 
    * @param cyclesToReserve how many cycles we want 
    * @return {@code true} if cycles are ours, {@code false} if not -- there's not enough left 
    */ 
    boolean tryReserve(int cyclesToReserve) { 
     int currentCycles = cycles.get(); 
     if (currentCycles < cyclesToReserve) 
      return false; 
     return cycles.compareAndSet(currentCycles, currentCycles - cyclesToReserve); 
    } 

} 
1

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

Таким образом, вы можете рассчитывать циклы на первом этапе и использовать тот же механизм для связи: перетаскивать объект-дозорный, который представляет «время остановки/приостановки этого потока», в очередь для первого этапа и при обработке он приостанавливает работу процессора (и все еще перенаправляет его на следующий этап, поэтому все этапы будут постепенно отключены). Например, вы можете расширить тип объектов, переданных в вашей очереди, чтобы иерархия содержала как реальные объекты полезной нагрузки (например, декодированные инструкции и т. Д.), Так и «объекты команд», подобные этому секундомеру остановки/паузы.

Другое асинхронное решение должно состоять из Thread.interrupt каждого потока и добавить проверку прерывания в ваш цикл обработки - это в основном для изящного закрытия и не для поддержки «паузы».

+0

Слово, которое вы ищете, это [«дозор»] (https://en.wikipedia.org/wiki/Sentinel_value), а не «яд» (т.е. значение, которое будет ловушкой, часто используемое для обнаружения чтений униализированных значений или [похожие случаи] (http://blog.hostilefork.com/poison-memory-without-asan/), чтобы взять случайный пример из google) –

+0

Нет, я искал яд. – BeeOnRope

+0

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

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

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