在 SBCL 等开源 Lisp 平台上运行 CL-HTTP (part 2)

标签: sbcl 开源 lisp | 发表时间:2011-07-07 16:12 | 作者:冰河 Sungelina
出处:http://tianchunbinghe.blog.163.com
在 SBCL 等开源 Lisp 平台上运行 CL-HTTP (part 2) - 冰河 - Chun Tian (binghe)

书接上文。

在 Clozure CL 上启动 CL-HTTP

CL-HTTP 在 Clozure CL (CCL) 上跑得比 SBCL 更好一些,因为 CCL 的多线程 API 特性更加丰富,与 CL-HTTP 的可移植兼容层的吻合度也比较高。CCL 是我最喜爱的开源 Common Lisp 实现。它由商业公司维护,性能稳定可靠,并且在所有支持的 OS/CPU 组合上都有多线程支持以及 32/64 位版本 (ARM 除外,只有 32 位),在 Mac OS X 上甚至还有一个 IDE。目前最后发布的 CCL 版本 1.6 支持下列五种操作系统:
  • Mac OS X (PowerPC and x86)
  • Linux (ARM, PowerPC and x86)
  • FreeBSD (x86)
  • Solaris (x86)
  • Microsoft Windows (x86)
安装 Clozure CL 的过程非常简单,首先按照用户所在的平台将对应的源代码和二进制文件一次性地从 SVN 上 checkout 下来。例如,对于 Mac OS X 上的版本 1.6,相应的 SVN URL 是:

http://svn.clozure.com/publicsvn/openmcl/release/1.6/darwinx86/ccl

只需调整 URL 中的版本号部分即可获得 CCL 的其他版本 (目前的可用范围是 1.2 - 1.7)。对于版本 1.6 来说,平台目录除 darwinx86 以外还包括下列平台组合:
  • darwinppc
  • freebsdx86
  • linuxarm
  • linuxppc
  • linuxx86
  • solarisx86
  • windows
Clozure CL 项目以一种奇特的方式将所有文件放在 SVN 里管理,所有二进制目录里使用 svn:external 属性链接到相应的源代码目录和预处理头文件 (cdb) 目录上。由于 CCL 是完全自举架构的,即新版本的 CCL 二进制文件是从老版本的 CCL 加载新的源代码以后生成的,因此二进制文件是作为构建 CCL 新版本的原材料来管理的。另外每当一些产生一些重要的源代码修改时,自举过程可能短暂地需要人工干预,这些工作通常是由 CCL 核心开发者来处理并提交修复后的二进制文件。

将 CCL 随便安装在任何目录里(所谓安装也就是找个地方就地 svn checkout 上述 URL),然后要做的事情包括以下两点:
  1. 定义一个环境变量 CCL_DEFAULT_DIRECTORY,使其内容等于 CCL 的安装路径。
  2. Windows 上需要设置环境变量,将 %CCL_DEFAULT_DIRECTORY% 写入 PATH 环境变量中;其他平台上推荐将 $CCL_DEFAULT_DIRECTORY/scripts 目录下的 ccl 和 ccl64 两个脚本软链接到 PATH 环境变量所包含的某个目录里,例如 /usr/local/bin。
CCL 的启动方法是,Windows 下打开一个命令提示符窗口,然后根据自己系统的实际情况执行 wx86cl 或者 wx86cl64;其他平台下根据实际情况执行 cclccl64。如果顺利启动的话应该可以看到类似下面的提示:

binghe@binghe-mac:~$ ccl64
Welcome to Clozure Common Lisp Version 1.6-r14820  (DarwinX8664)!
? 

关于 Clozure CL 使用方法的其他问题,尤其是当源代码出现更新以后的重编译方法,请参阅官方文档

在 Clozure CL 上启动 CL-HTTP 的方法跟在 SBCL 上是完全一样的。即首先加载 contrib/kpoeck/port-template/load.lisp,然后再用 (compile-all) 编译所有源代码,(http::start-examples) 启动示例站点(浏览器中的效果如本文插图所示)。CCL 的编译速度非常快。

不过需要注意的是,CL-HTTP 的 SBCL 和 CCL 移植是通过 kpoeck 的 port-template 框架进行的,这个框架的缺点在于 HTTP 请求的多线程处理相关代码还很不成熟。当 HTTP 服务器启动以后,Lisp 环境中只有一个 HTTP 监听器线程:

* (sb-thread:list-all-threads)

(#<SB-THREAD:THREAD "Stupid cl-http-accept-thread" RUNNING {1004BABBD1}>
 #<SB-THREAD:THREAD "initial thread" RUNNING {10048393C1}>)

对于每个新的 HTTP 请求,CL-HTTP 都会临时派生一个新线程处理,一旦处理完毕线程就会退出;对于多并发的请求来说性能成问题。因此 CL-HTTP 的 SBCL 和 CCL 移植目前还无法胜任产品级的应用需求。不过一旦学会了 CL-HTTP 的使用方法,以后可以进而使用 LispWorks、MCL、SCL 甚至 CMUCL 等平台运行产品级的 CL-HTTP 应用。

注意到示例站点的 URL 为 http://localhost:8000。如果想要在其他 IP 地址或者端口上运行示例站点,可以带参数调用 HTTP::START-EXAMPLES 函数,语法是:

http::start-examples &key host port (type :stupid-multi)

其中 host 是字符串格式的主机名或 IP 地址,port 是数值格式的端口,type 是一个关键字参数,除了 :stupid-multi 以外另一个可用的值是 :single,这导致 CL-HTTP 可以运行在单线程模式下,每次处理一个请求,并且上述函数将不会返回。单线程模式易于调试,甚至有可能把 CL-HTTP 跑在不支持多线程的 SBCL 版本上。

(有资料表明,很多 Lisp 程序员将 CL-HTTP 与 Hunchentoot 一起混用,Hunchentoot 用来提供多线程处理和 HTTP 协议的实现,CL-HTTP 负责生成动态 HTML/XHTML 代码。本系列文章的后续部分会简要介绍 CL-HTTP 的 HTML 生成宏。)

保存 SBCL 和 CCL 下的编译成果

在前述的 CL-HTTP 加载过程中,每次执行 (COMPILE-ALL) 时都要重新编译 CL-HTTP 的所有源代码。通常,使用 ASDF 或者 MK:DEFSYSTEM 的 Lisp 程序是可以做到按需编译的,但 CL-HTTP 的 port-template 似乎有意关闭了按需编译以确保 CL-HTTP 代码的加载过程具有某种确定性。对于 CL-HTTP 这种规模比较大并且代码相对稳定的项目来说,每次加载不同的用户站点代码时都要重新编译整个 CL-HTTP 是不值得的(我最近在基于 MIPSel 的嵌入式系统上使用 SBCL 1.0.28 完整编译 CL-HTTP 花掉了 1 小时 36 分,而在我最好的电脑上这个过程只需 40 秒),因此推荐的做法是在着手开发用户站点之前,先将 CL-HTTP 中除了示例站点以外的代码以二进制形式导出到一个 core (或 image,不同的 Lisp 平台有各自推荐的扩展名,导出的文件不能跨平台使用) 文件中,从而实现快速加载。

SBCL 下的做法如下:

首先进入 port-template 的根目录(也就是 CL-HTTP 源代码的 contrib/kpoeck/port-template 目录),然后不加载用户初始化文件启动 SBCL,然后依次输入红色标识的三个命令:

binghe@binghe-mac:~/Lisp/cl-http/contrib/kpoeck/port-template$ sbcl --no-userinit
This is SBCL 1.0.49.78-0bce932, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
* (load "load.lisp")
* (compile-all)
* (save-lisp-and-die "cl-http.core")

这样就在当前目录下得到了一个 cl-http.core 文件,以后可以使用命令行 sbcl --core cl-http.core 从该文件启动 SBCL (如果从其他目录启动 SBCL 则需要提供该文件的全路径)。事实上 SBCL 在不使用 --core 命令行参数启动时也会加载一个默认的 sbcl.core 文件,其中含有 Common Lisp 语言的实现和一些 SBCL 自己的语言扩展。从某种意义上来说,一个 Lisp 程序本质上就是对 Lisp 语言的扩展,用户代码和语言本身的实现代码在本质上是一样的,在 core 文件中的地位也是均等的。当然,诸如 car 和 cdr 这些底层 Lisp 函数最终上会被映射到 C 语言编写的底层 runtime 函数上。对 SBCL 的内部结构感兴趣的读者可以参考 SBCL Internals wiki 站点。关于 sb-ext:save-lisp-and-die 的详细说明请参见 SBCL 官方手册

Clozure CL 下的过程是类似的,不过 CCL 将 core 文件称为 image 文件。导出方法是类似的,首先不加载用户初始化文件启动 CCL,然后执行同样的前两个命令编译 CL-HTTP,最后用一个不同的命令导出 image 文件:

binghe@binghe-mac:~/Lisp/cl-http/contrib/kpoeck/port-template$ ccl64 -n
Welcome to Clozure Common Lisp Version 1.6-r14820  (DarwinX8664)!
? (load "load.lisp")
? (compile-all)
? (save-application "cl-http.image")

最后得到的 cl-http.image 文件可以使用 CCL 命令行 -I cl-http.core 来加载,注意 32 位和 64 位的 image 不能通用。关于 CCL:SAVE-APPLICATION 命令的其他细节请参见 CCL 官方手册

一旦以带有 CL-HTTP 的 core 或 image 文件启动了 SBCL 或 CCL,仍然可以继续使用 (HTTP::START-EXAMPLES) 来启动示例站点。这样可以大幅节省启动时间,并且为后面开发用户站点打下了一个良好的基础。

(未完待续)

相关 [sbcl 开源 lisp] 推荐:

在 SBCL 等开源 Lisp 平台上运行 CL-HTTP (part 1)

- 旺旺 - Chun Tian (binghe)
现在我来说明在 4 种开源 Common Lisp 平台上运行 CL-HTTP 的方法,四种平台分别是 SBCL、Clozure CL、CMUCL 和 Macintosh Common Lisp (MCL). 我相信我所提供的这些信息对某些 Common Lisp 爱好者来说将是梦寐以求的. 过去我也曾在博客里多次提到 CL-HTTP,多年来也一直在实际地学习和使用这个软件.

在 SBCL 等开源 Lisp 平台上运行 CL-HTTP (part 2)

- Sungelina - Chun Tian (binghe)
在 Clozure CL 上启动 CL-HTTP. CL-HTTP 在 Clozure CL (CCL) 上跑得比 SBCL 更好一些,因为 CCL 的多线程 API 特性更加丰富,与 CL-HTTP 的可移植兼容层的吻合度也比较高. CCL 是我最喜爱的开源 Common Lisp 实现. 它由商业公司维护,性能稳定可靠,并且在所有支持的 OS/CPU 组合上都有多线程支持以及 32/64 位版本 (ARM 除外,只有 32 位),在 Mac OS X 上甚至还有一个 IDE.

《Practical Common Lisp 中文版》样章

- 夜深 - Chun Tian (binghe)
(注:我的译作《Practical Common Lisp 中文版》将由人民邮电出版社图灵公司出版,不过由于种种原因目前该书还在紧张的编辑之中,最后确定的出版时间为 10 月底之前. 由于拖得比较久,个人感到愧对读者,因此经过和出版社的协商,现公开其中的一章供读者预览. 内容直接来自未经编辑的原始译稿,因此本文和最后出版的内容将在细节上有所出入,还请读者见谅) 第五章 函数 (英文原版).

使用Lisp搭建独立博客

- Linker Lin - loop_in_codes
使用Lisp搭建独立博客Author:Kevin LynxDate:9.29.2011Contact:kevinlynx at gmail dot com. 本文描述如何使用Lisp工具集搭建一个完整的个人博客站点. 一个搭建好的例子站点可以参看我的个人博客:http://codemacro.com.

《实用 Common Lisp 编程》译者序

- yat - Chun Tian (binghe)
最近忙得脚打后脑勺,但博客还要持续更新,所以无奈之下只好把我给《实用 Common Lisp 编程》一书撰写的译者序重新发表在这里,以方便那些尚未读过该书的潜在读者们. 说实话,今天重读了一遍以后,我被我自己写的文字给深深打动了,因为我的写作能力很不稳定,一篇好文不是随时都可以写得出来的. 也许这就是会写字的人和职业写手的区别所在吧.

至今听到关于 Lisp 最迷人的故事

- Ben - 译言-每日精品译文推荐
来源Amazing Lisp story ever heared. 在 ILC 2002 大会上前Lisp大神,当今的Python狂热者Peter Norvig,由于某些原因,做一个类似于马丁路德在梵蒂冈宣扬新教的主题演讲,因为他在演讲中大胆地声称Python就是Lisp. 讲完后进入提问环节,出乎我意料的是,Peter点了我过道另一侧,靠上面几排座位的一个老头,他衣着皱褶,在演讲刚开始的时候踱步进来,然后就靠在了那个座位上面.

Lispの創案者、ジョン・マッカーシー逝去(84歳)

- 三十不归 - TechCrunch Japan
Lispの創案者であり、現代人工知能の父ともいうべきジョン・マッカーシー(John McCarthy)が今日(米国時間10/24)逝去した. マッカーシーはプリンストンで〔映画「ビューティフルマインド」のモデルにもなったノーベル賞受賞者〕有名なジョン・ナッシュの下で数学を学び、その後、アメリカと当時のソ連の科学者の間で世界で最初のコンピュータ同士のチェス対局を実現させた.

【外刊IT评论网】为什么我喜欢Lisp语言

- EK - 外刊IT评论
本文是从 Why I love Lisp 这篇文章翻译而来. 这篇文章是我在Simplificator——我工作的地方——的一次座谈内容的摘录,座谈的题目叫做“为什么我喜欢Smalltalk语言和Lisp语言”. 在此之前,我曾发布过一篇叫做“ 为什么我喜欢Smalltalk. 大漠黄沙 by Guilherme Jófili.

巨星殞落!人工智慧之父、LISP 語言發明人 John McCarthy 去世

- chitsaou - T客邦
在 1956 年提出「Artificial Intelligence」一詞而被稱為人工智慧之父的 John McCarthy 於10月23日過世. 2011年10月可說是科技界傷心的時期,10月5日賈伯斯逝世、10月13日 C 語言之父 Dennis Ritchie 逝世,如今又一顆巨星殞落. ▲ Stanford Engineering(史丹佛大學工學院)在官方推特上宣佈大師過世的消息.