ФЭНДОМ


C H Forsyth: написал о том, каков общий подход при решении проблем с неустойчивыми соединениями

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

Если для этого вы воспользовались timers(2) вы получите процесс который взаимодействует при помощи alt с двумя каналами: один будет поставлять вам пакеты/сообщения/данные все что вы пытаетесь измерить по времени; и второй канал выдающий вам сообщения от таймера.

В appl/cmd/palm/palmsrv.b есть пример являющийся ядром такого подхода:

  Pchan.slp_read(p: self ref Pchan, timeout: int): (ref Sblock, string)
    {
       clock := Timer.start(timeout);
       alt {
       <-clock.timeout =>
          if(debug)
             sys->print("SLP: timeout\n");
          return (nil, "SLP: timeout");
       b := <-p.rd =>
          clock.stop();
          return (b, nil);
       }
  }


В этом примере таймауты достаточно большие. p.rd это канал к процессу который считывает байты через последовательный порт Palm pilot через протокол SLP, собирает из них полное сообщение и отправляет его в p.rd. clock это канал представляющий таймер.

В качестве альтернативы можно не пользоваться timers(2) а сделать это напрямую как в /appl/lib/dhcpclient.b

Другой возможностью является запуск процесса который просто засыпает на некоторое время, а потом убивает читающий процесс, и процесс который производит чтение при успешно завершенной операции получения данных убивает спящий процесс. Возможно, это даже лучше чем прием "все-или-ничего" в /appl/cmd/auth/logind.b когда запрос должен прибыть в строго указанное время прежде чем сервис перестанет его дожидаться.

timers(2) использует один единственный процесс для своей работы, так что он более удобен, однако другие техники тоже полезны. В случае dhcpclient был использован самый низкий уровень для работы на встраиваемых системах, чтобы отказаться от множества связанных модулей.