Какой самый простой способ прекратить (отравить) процесс производителя в Occam?

Мое приложение occam-pi имеет длительный процесс создания, определенный следующим образом:

PROC producer (VAL INT start, step, CHAN OF INT c!)
  INT count:
  SEQ
    count := start
    WHILE TRUE
      SEQ
        c ! count
        count := count + step
:

Отправляет значение на канал c увеличивается от start от step, Полный пример доступен здесь.

Это прекрасно работает, и я уверен, что бесконечные циклы идиоматичны в CSP. Проблема возникает, когда мой алгоритм потребления закончен. В этом примере тупик возникает, когда потребитель заканчивает работу.

TAGGED.INT Протокол, описанный здесь, пытается решить проблему закрытия сети процессов, однако, из моего текущего понимания, не существует простого метода для завершения производителя, чья основная работа отправляется по каналу. Кажется, что единственный способ остановить продюсера - это использовать какой-то канал управления и чёрную дыру:

PROTOCOL CONTROL
  CASE
    poison
:

PROTOCOL TAGGED.INT
  CASE
    normal; INT
    poison
:

PROC producer (VAL INT start, step, CHAN OF TAGGED.INT c!, CHAN OF CONTROL control?)
  INT count:
  INITIAL BOOL running IS TRUE:
  SEQ
    count := start
    WHILE running
      SEQ
        PRI ALT
          control ? poison
            SEQ
              running := FALSE
              c ! poison      -- necessary, only to kill the black hole process 
          SKIP
            SEQ
              c ! normal; count
              count := count + step
:

Полный рабочий пример доступен здесь. Проблема в том, что код гораздо более нечитабелен - субъективен, я знаю, но важен для разработки программного обеспечения - первоначальное намерение замысловато по сравнению с оригинальным. Это кажется противоречивым бритве Оккама!

С JCSP, C++ CSP2 и python-csp канал может быть явно отравлен, чтобы отключить сеть процессов. По какой-то причине спор о том, как это сделать, загрязняет код логикой выключения и кажется нелогичным.

Таким образом, вопрос заключается в том, есть ли способ завершения процесса производителя без использования явного control канал как в примере?

РЕДАКТИРОВАТЬ:

Потенциально больше информации по этой теме содержится в этом архиве списка рассылки ( Poison), это довольно старая (> 10 лет). Таким образом, вопрос остается открытым, изменилось ли что-нибудь с тех пор, или это лучший способ добиться "завершения процесса" в occam-pi?

1 ответ

Решение

Таким образом, вопрос заключается в том, существует ли способ завершения процесса производителя без использования явного канала управления, как в примере?

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

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

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

Код Occam 2.1:

PROC producer( VAL INT start, step, CHAN INT data, CHAN BOOL control)
  BOOL running:
  INT  count:
  SEQ
    count, running := start, TRUE
    WHILE running
      SEQ
        data    ! count
        control ? running
        count := count + step
: -- producer

PROC main( CHAN BYTE inp, out, err)
  CHAN INT data:
  CHAN BOOL control:
  VAL INT amount IS 10:
  INT val:
  PAR
    producer( 0, 4, data, control)
    SEQ n= 1 FOR amount
      SEQ
        data    ? val
        control ! n < amount
        out.int( val, 0, out)
        out.string( "*n", 0, out)
: -- main
Другие вопросы по тегам