multithreading - 在 ABCL(武装熊)LISP 中,我如何创建后台子进程/后台线程?

标签 multithreading lisp common-lisp abcl

如何在 ABCL 中产生一个后台(命名的)子进程/线程?也就是说,我想生成在后台运行的子进程(或线程),并将顶级评估留给其他处理。

使用 (apropos 'process/thread) 我发现了像下面列出的那些未记录的函数,但我无法弄清楚语法。我正在寻找要遵循/修改的运行示例代码。我似乎已经使用以下 make-process 函数创建了一个进程,但是当我试图杀死它时出现错误,它在前台运行。 ABCL 手册中没有关于 make-process 的条目。 MAKE-THREAD 已列出,但未记录

ABCL 手册中列出的带有“未记录”标记的所有函数的文档/示例在哪里? (还有那些带有 apropos 的?)

作为一个单独但相关的问题,是否有一个包含 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 ...) 

[可能为线程创建必要流的语法/示例?]

在此先感谢您的指点或代码。

最佳答案

我将 ABCL 与 roswell 结合使用所以它很容易与 quicklisp 结合使用,但也有一个项目 that ,但我认为您可以轻松地使用 quicklisp 或在 ABCL 中加载库。您可以在 ABCL 上加载很多来自 quicklisp 的库,不幸的是不是全部(Quicklisp 在 linux 和 SBCL 上进行了测试),但是为了并发,您可以加载我通常使用的两个很棒的库 bordeaux-threads (common lisp 中的常见威胁库)和 Chanl一个将 go channel 移植到普通 lisp 的库。您可以尝试其他方法,但我不确定它们是否适用于 lparallel、cl-actors ...

让我们用这个库做一个例子:

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 actors 或其他 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)

它还实现了 mailbox威胁将消息传递给线程

关于multithreading - 在 ABCL(武装熊)LISP 中,我如何创建后台子进程/后台线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50362129/

相关文章:

.net - 代码应该对CPU内存模型做出哪些假设,以及如何记录这些假设?

c++ - 过多的线程数会在文件读取时产生更好的结果

Emacs 练习变得更加舒适和熟悉编辑器本身以及 Lisp?

lisp - Common Lisp 宏和 Forth 元编程能力的比较

matrix - Lisp 中矩阵代数的行和列标签

Java、FTP服务器和客户端

c# - 使用 Parallel.for 循环的文件 I/O 问题

compiler-construction - 编译语言可以是谐音的吗?

printing - 为什么我的结果是 (# # #)?

windows - clozure cl : cl-freetype2 on windows 7