Multithreading 不覆盖*标准输入*可防止多线程
我有一个通用的Lisp程序,根据我如何使用Multithreading 不覆盖*标准输入*可防止多线程,multithreading,lisp,common-lisp,ecl,Multithreading,Lisp,Common Lisp,Ecl,我有一个通用的Lisp程序,根据我如何使用*标准输入*,它的行为会有所不同。详情如下: (if input-stream? (process) (with-open-file (*standard-input* up :element-type 'unsigned-byte) (process))) 进程函数启动多个线程。每个线程读取标准输入的一部分,将其写入一个文件(全部在锁内),并并行处理生成的文件(在锁外)。事实上,它只在输入流?为false的情况下并行处理生
*标准输入*
,它的行为会有所不同。详情如下:
(if input-stream?
(process)
(with-open-file (*standard-input* up :element-type 'unsigned-byte)
(process)))
进程
函数启动多个线程。每个线程读取标准输入的一部分,将其写入一个文件(全部在锁内),并并行处理生成的文件(在锁外)。事实上,它只在输入流?
为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上运行。我通过以下方式之一运行它:
- 我的问题有错。现在没事了
- 添加了
功能,并描述了如何运行程序进程
*标准输入*
必须是文本文件,您的是二进制文件。不知道这对你的情况是否重要。我认为你需要提供关于如何“运行”这个程序的详细信息,以及进程的作用。我尝试了一个文本文件,没有什么不同。我刚刚添加了请求的详细信息。为什么不按顺序将输入分发到文件中(因为您正在这样做,只是通过锁定),然后并行处理这些文件?另外:读取顺序
@tfb感谢建议的解决方法。如果我这样做,而我的输入文件是X兆字节,我将需要2*X的磁盘空间来进行处理。我可能没有那么多。