我有一个 Common Lisp 程序,它的行为取决于我使用的方式*standard-input*
。以下是详细信息:
(if input-stream?
(process)
(with-open-file (*standard-input* up :element-type 'unsigned-byte)
(process)))
该process
函数启动多个线程。每个线程读取标准输入的一部分,将其写入文件(全部在锁内)并并行处理生成的文件(在锁外)。事实上,它仅在以其他方式按顺序处理它们的情况下并行处理input-stream?
生成的false
文件。
(defun process ()
(let ((psize 4194304)
(stream *standard-input*)
(result-lock (bt:make-lock))
(input-stream-lock (bt:make-lock))
eof)
(flet ((add-job (fname)
(make-thread
#'(lambda ()
(do () (eof)
(when (bt:with-lock-held (input-stream-lock)
(unless eof
(setq eof (write-input-stream-to-file stream fname psize))
t))
(sleep 0.1)
(bt:with-lock-held (result-lock)
(display-progress))))))))
(mapcar
#'join-thread
(loop for i from 1 to 10
collect (add-job
(make-pathname :directory "/tmp"
:name "test"
:type (princ-to-string i))))))))
(let ((counter 0))
(defun display-progress ()
(if (zerop (mod (incf counter) 10))
(format t " ~a " counter)
(write-char #\+))))
(defun write-input-stream-to-file (stream fname psize-bytes)
(with-open-file (out fname
:direction :output
:element-type 'unsigned-byte
:if-exists :supersede)
(do ((byte (read-byte stream nil nil)
(read-byte stream nil nil))
(offset 0 (1+ offset)))
((or (= offset psize-bytes) (null byte)) (not byte))
(write-byte byte out))))
如果我们创建一个 FIFO(使用 mkfifo),将文件复制到它并使用它运行程序,我们再次观察到并行性。
上面的程序是使用 ECL 作为命令行实用程序构建的,并在 Linux 上运行。我以下列方式之一运行它:
- 猫“大文件”| 我的程序
- 我的程序“大文件”
并行性仅在情况 2 中发生。
问题是为什么会有差异?
更新:
- 我的问题有误。现在可以了。
- 添加了
process
功能并描述了我如何运行程序