Spec-Zone.ru › Elisp

Сентинелы: обнаружение изменений состояния процесса

Сентинел процесса — это функция, которая вызывается при любом изменении состояния связанного с ней процесса по любой причине, в том числе при получении сигналов (отправленных Emacs или вызванных собственными действиями процесса), которые завершают, приостанавливают или возобновляют процесс. Сентинел процесса также вызывается при завершении процесса. Сентинел получает два аргумента: процесс, в котором произошло событие, и строку с описанием типа события.

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

Строка с описанием события выглядит одним из следующих образом (однако этот список строк событий не является исчерпывающим):

  • "finished\n".
  • "deleted\n".
  • "exited abnormally with code exitcode (core dumped)\n". Часть «дамп ядра создан» необязательна и появляется только в том случае, если процесс создал дамп ядра.
  • "failed with code fail-code\n".
  • "signal-description (core dumped)\n". signal-description — это зависящее от системы текстовое описание сигнала, например "killed" для SIGKILL. Часть «дамп ядра создан» необязательна и появляется только в том случае, если процесс создал дамп ядра.
  • "open from host-name\n".
  • "open\n".
  • "run\n".
  • "connection broken by remote peer\n".

Сентинел выполняется только тогда, когда Emacs ожидает чего-либо (например, ввода с терминала, истечения времени или вывода процесса). Это позволяет избежать ошибок синхронизации, которые могли бы возникнуть, если бы сентинелы запускались в произвольные моменты во время выполнения других программ на Lisp. Программа может ожидать, чтобы сентинелы могли выполняться, вызвав sit-for или sleep-for (см. Ожидание истечения времени или ввода) либо accept-process-output (см. Получение вывода от процессов). Emacs также позволяет сентинелам выполняться, когда цикл команд считывает ввод. delete-process вызывает сентинел при завершении работающего процесса.

Emacs не хранит очередь из нескольких причин для вызова сентинела одного процесса; он записывает только текущее состояние и факт его изменения. Поэтому два изменения состояния, произошедшие одно за другим, могут привести лишь к одному вызову сентинела. Однако при завершении процесса сентинел всегда запускается ровно один раз. Это объясняется тем, что после завершения состояние процесса уже не может измениться.

Перед запуском сентинела процесса Emacs явно проверяет наличие вывода от процесса. После запуска сентинела вследствие завершения процесса дальнейший вывод от процесса уже поступить не может.

Сентинел, который записывает вывод в буфер процесса, должен проверять, существует ли ещё этот буфер. Если он попытается вставить текст в уже закрытый буфер, возникнет ошибка. Если буфер закрыт, (buffer-name (process-buffer process)) возвращает nil.

Во время работы сентинела прерывание обычно запрещено — иначе последствия нажатия C-g на уровне команд или попытки прервать пользовательскую команду были бы непредсказуемыми. Если вы хотите разрешить прерывание внутри сентинела, свяжите inhibit-quit с nil. В большинстве случаев правильнее всего сделать это с помощью макроса with-local-quit. См. Прерывание.

Если во время выполнения сентинела возникает ошибка, она перехватывается автоматически, чтобы не остановить выполнение программ, работавших в момент запуска сентинела. Однако если debug-on-error не равно nil, ошибки не перехватываются. Это позволяет использовать отладчик Lisp для отладки сентинела. См. Отладчик Lisp. Если ошибка перехвачена, Emacs приостанавливается на process-error-pause-time секунд, чтобы пользователь успел её увидеть. См. Создание асинхронного процесса.

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

Обратите внимание: Emacs автоматически сохраняет и восстанавливает данные о совпадениях во время выполнения сентинелов. См. Данные о совпадениях.

Функция: set-process-sentinel process sentinel

Эта функция связывает sentinel с process. Если sentinel равно nil, для процесса будет использоваться сентинел по умолчанию, который при изменении состояния процесса добавляет сообщение в буфер процесса.

Изменения сентинелов процесса вступают в силу немедленно: если сентинел уже запланирован к запуску, но ещё не был вызван, а вы укажете новый сентинел, при последующем вызове будет использоваться новый.

(defun msg-me (process event)
   (princ
     (format "Process: %s had the event '%s'" process event)))
(set-process-sentinel (get-process "shell") 'msg-me)
     ⇒ msg-me
(kill-process (get-process "shell"))
     -| Process: #<process shell> had the event 'killed'
     ⇒ #<process shell>
Функция: process-sentinel process

Эта функция возвращает сентинел для process.

Если необходимо передавать изменения состояния процесса нескольким сентинелам, можно использовать add-function, чтобы объединить существующий сентинел с новым. См. Добавление советов к функциям Emacs Lisp.

Функция: waiting-for-user-input-p

Во время работы сентинела или функции-фильтра эта функция возвращает значение, отличное от nil, если в момент вызова сентинела или функции-фильтра Emacs ожидал ввода с клавиатуры от пользователя, или nil, если это было не так.

Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Sentinels.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API