Получение общего идентификатора процесса Lisp в Linux - PullRequest
0 голосов
/ 13 октября 2018

Мне интересно, есть ли способ получить PID (идентификатор процесса) Linux из REPL Common Lisp.То есть я хотел бы узнать идентификатор процесса SBCL или Allegro из REPL самого процесса.

Ответы [ 3 ]

0 голосов
/ 13 октября 2018

Существует (в основном) портативный способ сделать это.CL обеспечивает чтение файлов, и можно заметить, что pid текущего процесса находится в /proc/self/status (также /proc/self является символической ссылкой на pid процесса, но я не думаю, что есть переносимая ссылка для чтения).

В частности /proc/self/status представляет собой текстовый файл и содержит строку, которая выглядит следующим образом:

Pid: 439

Таким образом, вы можете проанализировать файл, чтобы извлечь его.

Но тогда, когда у вас естьpid, с этим мало что можно сделать без системных вызовов или /proc странностей

0 голосов
/ 13 октября 2018

Окончательное решение (по большей части @Dan Robertson's и @coredump - спасибо, ребята!)

На самом деле @Dan Robertson дал полный ответ - я понимаю в ретроспективе.Этот ответ является просто реализацией того, что он сказал.Так что дайте ему очки!

(ql:quickload "CL-PPCRE") ;; for regex parsing

(defun get-this-pid ()
  "Return PID of this current lisp process."
  (with-open-file (in #P"/proc/self/status")
    (loop for line = (read-line in nil)
      while line
      when (ppcre:scan "^Pid" line)
        do (return (car
            (ppcre:all-matches-as-strings "\\d+" 
                              line))))))

;; to get current process id, call:
(get-this-pid) ;
;; returns for me at the moment using sbcl "12646"
;; this is correct as closing of all other sbcl processes
;; and doing "pidof sbcl" in the shell showed.

Как указывал @Don Robertson, файл /proc/self/status показывает программе, которая открывает ему свой номер "PID" (каждая программа видит это по-своему).Спасибо, Дон, так как это решает проблему поиска действительно PID программы (pidof sbcl в оболочке даст несколько цифр, если несколько программ lisp работают независимо на машине. Вызов внешних программ устарел, если мы откроем этот файлзатем изнутри cl, как указал @coredump.

номера PID других программ

;; Thanks to @coredump - who suggested to use 
;; `ppcre:split :whitespace-char-class` for capturing arbitrary numbers
;; in the answer string - I added a test for integer-string-p to clean
;; non-numberic values after split.

(ql:quickload "CL-PPCRE")

(defun integer-string-p (string)
  "Does string constist only of '01234567890' characters?"
  (reduce (lambda (x y) (and x y))
      (mapcar (lambda (c) (member c (coerce "1234567890" 'list)))
          (coerce string 'list))))

(defun extract-integers-from-string (s)
  "Return integer-words of s."
  (let ((l (ppcre:split :whitespace-char-class s)))
    (remove-if-not #'integer-string-p l)))

(defun pid-numbers (program-name)
  "Return PID numbers of a program in current machine."
  (let ((pid-line (with-output-to-string (out)
            (external-program:run "pidof" (list program-name)
                      :output out))))
    (extract-integers-from-string pid-line)))

;; call it
(pid-numbers "sbcl")
(pid-numbers "firefox")

;; * (pid-numbers "sbcl")
;; ("16636" "12346")
;; * (pid-numbers "firefox") 
;; ("24931" "19388" "19122" "10800" "10745") ; yeah I have many open :D
0 голосов
/ 13 октября 2018

Нет ничего в спецификации Common Lisp, которая реализует это.Идентификаторы процессов слишком зависят от реализации.

В SBCL пакет SB-POSIX предоставляет интерфейсы Lisp для большинства системных вызовов POSIX, поэтому вы должны использовать (sb-posix:getpid).

* 1008.* В Allegro CL функции интерфейса операционной системы находятся в пакете EXCL.OSI, поэтому вы должны использовать (excl.ose:getpid)
...