CLozure CL 多线程函数使用实例

大城市里の小女人 提交于 2019-12-07 12:52:57

CLozure CL 多线程函数使用实例



一、简单介绍

Common Lisp 的标准没有对多线程的描述,因此各种 CL 实现都给出了自己的多线程功能函数,具体细节有所不同,这里大致讲解一下 Clozure CL 的多线程函数的简单用法(参照 CCL 的描述文档中多线程部分 第7章 Programming with threads)。 我在阅读CCL文档时被搞晕了,发现找不到线程对象作为参数的正确写法,后来经过 cn-lisp 的朋友指点,才发现不存在所谓的正确写法,只能把线程对象绑定到全局变量上使用,估计有人在学习 CCL 的多线程时会遇到类似的问题,所以这里把我的一点学习体会记录下来,希望能对其他初学者有所助益,帮助其他人少走些弯路。

二、CCL 线程函数基本知识

1、首先介绍几个线程相关的全局变量:

【全局变量】当前线程:*current-process*

在 ccl 中执行如下:

Welcome to Clozure Common Lisp Version 1.8-store-r15418  (DarwinX8664)!
?
? *current-process*
#<COCOA-LISTENER-PROCESS Listener(15) [Active] #x30200108839D>
? 

其中 #< . . . > 是线程对象的表示方式,第一列表示线程类型,第二列表示线程名称,小括号里面的数字表示线程序列号,方括号里的内容表示线程的状态,最后以 #x 打头的一串数字表示这个线程对象在内存中的地址。

【全局变量】每秒时间片 *TICKS-PER-SECOND*

顾名思义,就是把1秒钟的 CPU 资源平分为 100 份,每一份是一个时间片,时间片是一种系统资源,由 OS 统一调度

? *TICKS-PER-SECOND*
100
?

2、接着介绍两个 CCL 的 Toplevel 命令

【toplevel 命令】显示当前线程: :proc

? :proc
15 : -> Listener         [Active] 
13 :    sleeper          [Reset] 
10 :    sleeper          [semaphore wait]  (Suspended)
7 :    sleeper           [semaphore wait] 
5 :    housekeeping      [Sleep] 
0 :    Initial           [Reset] 
? 

【toplevel 命令】yield 指定线程

该命令可以用线程序列号或者线程名称字符串作为标识线程对象的参数。

使用线程序列号作为 process 参数

? (:y 13)

如下是使用线程名称字符串作为 process 参数

? (:y "sleeper)

3、最后介绍几个常用的线程函数

【函数】 显示全部 Lisp 线程:all-processes

? (all-processes)
(#<COCOA-LISTENER-PROCESS Listener(15) [Active] #x3020010F589D> #<PROCESS sleeper(13) 	[semaphore wait] #x3020010572ED> #<PROCESS sleeper(10) [semaphore wait] #x30200102EDED> 	#<PROCESS sleeper(7) [semaphore wait] #x302000E07A9D> #<PROCESS housekeeping(5) [Sleep] 	#x302000DF69FD> #<APPKIT-PROCESS Initial(0) [Reset] #x3020000C0B5D>)
?

####【注意】: CCL提供的线程函数对线程对象的引用方式比较麻烦,无法直接通过线程序列号或线程名称字符串来引用,只能通过把由线程相关函数返回的线程对象绑定到全局变量上的办法来引用。

实例如下:

把当前线程绑定到全局变量 *p* 上,如下 (defparameter *p* *current-process*):

? *current-process*
#<COCOA-LISTENER-PROCESS Listener(15) [Active] #x30200108839D>
? (defparameter *p* *current-process*)
*P*
? *p*
#<COCOA-LISTENER-PROCESS Listener(15) [Active] #x30200108839D>
? 

从线程列表中绑定一个线程对象到全局变量 *select-process* 上,例子中使用第3个

? (all-processes)
(#<COCOA-LISTENER-PROCESS Listener(15) [Active] #x3020010F589D> #<PROCESS sleeper(13) 	[semaphore wait] #x3020010572ED> #<PROCESS sleeper(10) [semaphore wait] #x30200102EDED> 	#<PROCESS sleeper(7) [semaphore wait] #x302000E07A9D> #<PROCESS housekeeping(5) [Sleep] 	#x302000DF69FD> #<APPKIT-PROCESS Initial(0) [Reset] #x3020000C0B5D>)
? (defparameter *select-process* (third (all-processes)))
*SELECT-PROCESS*
? *select-process*
#<PROCESS sleeper(10) [semaphore wait] #x30200102EDED>
? 

【函数】查看线程状态:process-whostate

? (process-whostate *select-process*)
"semaphore wait"
? 

三、其他线程函数

其余的线程函数都可以通过查询手册得到详细解释,就不多说了。

(说明:上述实例都在 Clozure CL 环境中执行通过;在 Emacs 环境中函数和全局变量可以执行,但是 Toplevel 命令无法执行)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!