ecl之多线程

来源:互联网 发布:辐射4光源优化 编辑:程序博客网 时间:2024/04/28 04:48

ecl是一种common lisp,特点是可以结合进C语言,至于效率,文档语焉不详,故也没有仔细研究。

下载了源代码后,普通的./configure配置make后生成的编译器是不能直接利用mp多线程库的,故./configure的过程要仔细研究。通过./configure --help可以得知有一个选项--enable-threads默认是关闭的,重新配置./configure --enable-threads,并make,此时启动ecl,出现了以下的界面:

ECL (Embeddable Common-Lisp) 10.4.1
Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya
Copyright (C) 1993 Giuseppe Attardi
Copyright (C) 2000 Juan J. Garcia-Ripoll
ECL is free software, and you are welcome to redistribute it
under certain conditions; see file 'Copyright' for details.
Type :h for Help.  
Top level in: #<process SI:TOP-LEVEL 0000000001bf6f60>.
>
注意倒数第二行出现了#<process SI:TOP-LEVEL 0000000001bf6f60>,这说明mp库可以使用了。

在ecl文档里有mp库函数的大致介绍,但是说实话,如果没有多线程编程的基础知识,很难看懂它在说什么。大致说来,多线程编程需要把业务分成许多并列的部分,然后开几个线程来分别完成这些业务。所以需要有函数mp:process-run-function:创建一个线程,这个线程运行一个已知函数。也可以用mp:process-preset和mp:make-process来分别做这两件事。线程完成时要退出,这有函数mp:exit-process,该函数没有参数,在线程中直接调用,哪个线程调用就退出哪个线程。

如果多个线程要同时对一个变量进行写操作就要用到线程同步和锁机制,原因在于线程的切换可以在任意时刻,如果一个线程正在进行写变量操作却被切换,就会造成写变量操作没有完成而产生计算错误,所以写变量操作应该是一个不可分割的整体,称为原语。具体说来,可以在线程里使用mp:with-lock函数,这表示不能有两个线程同时执行此段代码,而只能有一个线程执行,当它执行时,其他线程可以查询其是否已执行完毕,如完毕,其他线程可以执行。

下面编一个多线程求解0*0+1*1+...+9*9的和的程序,这里使用了9个线程,每个线程解决一项,最后求和的时候,每个线程都要把乘积项加到总和变量n上,显然,当一个线程加乘积项的时候,别的线程只能等待,不能打断这个过程,否则就会错误。下面是程序:

(setq n 0)
(setq nt 10)
(defvar lockx (mp:make-lock :name 'ct))
(defun countx (x) (let ((y (* x x))) (mp:with-lock (lockx) (setq n (+ n y)) (setq nt (- nt 1))) (mp:exit-process)))
(defun start-threads ()                   
(let ((td)) 
  (do ((x 0 (+ x 1))) ((>= x 10))
    (setq td (mp:process-run-function 'cx #'countx x))  
    )
 (do (())((eq nt 0)))  
  (print n)
  )
)

载入源程序后执行start-threads函数即可。