task как интерфейс к системному вызову

Sergey ShishkinSergey Shishkin
2 min read

Цитируем с переводом авторскую статью Using 'task'. Существуют ли какие-либо существующие функции PicoLisp для использования системного вызова 'select' и выполнения асинхронного ввода-вывода? Да. Фактически, это основа почти всех действий в типичном приложении. Основная структура управления — это список файловых дескрипторов и выражений в глобальном '*Run', обычно в сочетании с интерфейсной функцией 'task'. Например, если вы хотите прослушивать несколько портов:

   (for P (4001 4002 4003 4004)
      (task (port P)
         (when (accept @)
            (task @
               Sock @
               (in Sock
                  (if (rd)
                     (out Sock (eval @))
                     (task Sock)
                     (close Sock) ) ) ) ) ) )

Прослушиваются четыре порта, и всякий раз, когда поступает запрос на соединение, task будет устанавливать новую задачу на этом сокете. Затем, всякий раз, когда данные поступают на этот сокет, они воспринимаются как выражение 'exe' и оцениваются с текущим выходным каналом, установленным на этот сокет. Если вместо этого поступает EOF, соединение закрывается, а “задача” удаляется.

Используйте этот механизм для связи между различными системами. Для связи с браузером вам лучше использовать line вместо rd и отправлять HTML-данные вместо (eval @) .

Обратите внимание, что все это происходит в "фоновом режиме". У вас все еще может быть какой-то основной цикл в вашей программе (или, если нет, вы будете перенесены в приглашение консоли ':'). Основной цикл "ничего не делать" - это wait , поэтому примеры для приложений часто имеют '-wait' в командной строке.

   (task (port 4444)
      (let? Sock (accept @)
         (in Sock (out Sock (eval (rd))))
         (close Sock) ) )

Существует бесконечное множество способов объединить task с функциями ввода-вывода. Простая «однократная» фоновая “задача”, принимающая запрос на порт 4444, считывающая выражение, оценивающая его и немедленно закрывающая соединение:

   (setq P (port 4444))
   (loop
      (task (listen P)
         (in (setq Sock @)
            (if (rd)
               (out Sock (eval @))
               (task Sock)
               (close Sock) ) ) ) )

Естетственно, что стоит приветсти и ссылку, на уже существующий пост, посвященный функциям - task и tasks.

0
Subscribe to my newsletter

Read articles from Sergey Shishkin directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sergey Shishkin
Sergey Shishkin

Всегда чему-то учусь!