В ABCL (Armed Bear) LISP как создать фоновый подпроцесс / фоновые потоки? - PullRequest
0 голосов
/ 16 мая 2018

Как мне создать фоновый (именованный) подпроцесс / поток в ABCL ? То есть я хочу запустить подпроцесс (или поток) для выполнения в фоновом режиме и оставить оценку верхнего уровня свободной для другой обработки.

Используя (apropos 'process / thread), я нашел недокументированные функции, подобные перечисленным ниже, но я не могу понять синтаксис. Я ищу пример кода с кодом , который следует / изменить. Кажется, я создал процесс со следующей функцией make-process, но я получаю сообщение об ошибке, когда пытаюсь его убить, и он запускается на переднем плане. Там нет записи в руководстве ABCL для make-процесса. MAKE-THREAD указан в списке, но как не задокументирован .

Где находится документация / примеры для всех функций, перечисленных в руководстве ABCL с этим обозначением " не документировано "? (Также найдены с уместным?)

Как отдельная, но связанная проблема, есть ли в Интернете хранилище примеров работающего кода, специфичных для ABCL, которые охватывают подобные вопросы?

В других распространенных списках я бы использовал такие функции, как:

(activate-process *initial-process*)

или

#+(:and MULTITASKING :lucid)
(defun mpd (&optional (reinit nil))
  (user::make-process :name "Pdraw-proc" :function #'pd::pdraw :args (list reinit)))

В ABCL я запутался, добравшись до:

CL-USER> (setf uu (make-thread (my-reader))) <-- runs at the top level / hogs read loop

CL-USER> (setf jj (system::%make-process (foo)))
#S(SYSTEM:PROCESS :JPROCESS 3 :INPUT NIL :OUTPUT NIL :ERROR NIL)
CL-USER> jj
#S(SYSTEM:PROCESS :JPROCESS 3 :INPUT NIL :OUTPUT NIL :ERROR NIL)


SYSTEM::MAKE-PROCESS (fbound)
SYSTEM::%PROCESS-KILL (fbound)
SYSTEM::%MAKE-PROCESS (fbound)

и

THREADS:MAKE-THREAD (fbound)
THREADS:DESTROY-THREAD (fbound)

и

(make-two-way-stream ...) 

[Синтаксис / примеры для создания необходимых потоков для потоков, может быть?]

Заранее спасибо за указатели или код.

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

С помощью подсказок типа Вибху я нашел то, что кажется тем же нативным решением, предложенным Анкеги.Спасибо за: имя arg!

CL-USER> (lisp-implementation-type)
"Armed Bear Common Lisp"
CL-USER> (lisp-implementation-version)
"1.3.3"
"Java_HotSpot(TM)_64-Bit_Server_VM-Oracle_Corporation-1.8.0_161-b12"
"amd64-Windows_7-6.1"
CL-USER> 


(setf my-val 1)

;;; Output to *standard-output* for Inferior Lisp, so careful with SLIME:
(defun make-my-thread ()
  (setf q
    (threads:make-thread
     #'(lambda ()
         (format t "I am alive!~%")
         (sleep 15)
         (format t "Goodbye Cruel World~%")
       (setf my-val (1+ my-val))))))


;;; Works, but takes a while: 
(defun kill-it () (threads:destroy-thread q))

(defun alivep () (THREADS:THREAD-ALIVE-P q))

(make-my-thread) запускается в фоновом режиме без зависаний стандартный ввод

my-val может быть запрошен и не устанавливается до окончания сна.

(alivep) возвращает T до тех пор, пока поток не завершится или до нескольких секунд после вызова kill-it, затем NIL.

Так что эта минимальная функциональность теперь дает мне большую гибкость для запуска потоков в фоновом режиме.

0 голосов
/ 16 мая 2018

Я использую ABCL с roswell , поэтому его легко использовать в сочетании с quicklisp, но есть также проект для , который , но я думаю, что вы могли бы легко использовать quicklisp или загрузить библиотеки в ABCL. Есть много библиотек, которые вы можете загрузить в ABCL из quicklisp, к сожалению, не все (Quicklisp проверен на linux & SBCL), но для параллелизма вы можете загрузить две замечательные библиотеки, которые я обычно использую bordeaux-threads (библиотека общих угроз в общем lisp) и Chanl библиотека, порты которой направляют каналы в общий lisp. Есть и другие, которые вы можете попробовать, но я не уверен, что они работают параллельно, коллеги-актеры ...

Давайте сделаем пример с этими библиотеками:

CL-USER> (lisp-implementation-type)
"Armed Bear Common Lisp"
CL-USER> (lisp-implementation-version)
"1.5.0"
"Java_HotSpot(TM)_64-Bit_Server_VM-Oracle_Corporation-1.8.0_162-b12"
"x86_64-Mac_OS_X-10.12.6"

CL-USER> (ql:quickload 'bt-semaphore)
To load "bt-semaphore":
  Load 1 ASDF system:
    bt-semaphore
; Loading "bt-semaphore"
[package bt-semaphore]
(BT-SEMAPHORE)
CL-USER> bt:*supports-threads-p*
T

CL-USER> (defparameter *counter* 0)
*COUNTER*
CL-USER> (defun test-update-global-variable ()
  (bt:make-thread
   (lambda ()
     (sleep 10)
     (incf *counter*)))
  *counter*)
TEST-UPDATE-GLOBAL-VARIABLE
CL-USER> *counter*
0 (0 bits, #x0, #o0, #b0)
CL-USER> (test-update-global-variable)
0 (0 bits, #x0, #o0, #b0)
CL-USER> *counter*
0 (0 bits, #x0, #o0, #b0)
CL-USER> (+ 2 3)
5 (3 bits, #x5, #o5, #b101)
CL-USER> (format t "I'm wainting for counter")
I'm wainting for counter
NIL
CL-USER> (format t "let'see the counter value ~a~%" *counter*)
let'see the counter value 1
NIL

CL-USER> (ql:quickload :chanl)
To load "chanl":
  Load 1 ASDF system:
    chanl
; Loading "chanl"

(:CHANL)

CL-USER> (chanl:pcall (lambda () (sleep 10) (incf *counter*)))
#<CHANL:TASK Anonymous task [ALIVE] {2360938E}>
CL-USER> *counter*
1 (1 bit, #x1, #o1, #b1)
CL-USER> ;; waiting
; No values
CL-USER> *counter*
2 (2 bits, #x2, #o2, #b10)

Обратите внимание, что это только пример, подразумевающий, что глобальная переменная не подходит для угроз, также посмотрите библиотеки для дальнейшей документации, которая должна работать. Кроме того, в ABCL легко использовать библиотеки Java, поэтому, возможно, Вы можете использовать актеры akka или другие библиотеки java для параллелизма

Кроме того, поскольку вы указали, что в ABCL есть пакет для угроз, его легко использовать, например:

CL-USER> (threads:make-thread (lambda () (sleep 10) (incf *counter*)) :name 'patata)
#<THREAD "PATATA" {49998577}>
CL-USER> *counter*
2 (2 bits, #x2, #o2, #b10)
CL-USER> ; wait
; No values
CL-USER> *counter*
3 (2 bits, #x3, #o3, #b11)

Также реализовано почтовый ящик угроз для передачи сообщений в потоки

...