Multithreading 不覆盖*标准输入*可防止多线程

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的情况下并行处理生

我有一个通用的Lisp程序,根据我如何使用
*标准输入*
,它的行为会有所不同。详情如下:

(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上运行。我通过以下方式之一运行它:

  • cat“大文件”|我的程序
  • 我的程序“大文件”
  • 并行性只发生在情况2中

    问题是为什么会有不同

    更新:

    • 我的问题有错。现在没事了
    • 添加了
      进程
      功能,并描述了如何运行程序

    *标准输入*
    必须是文本文件,您的是二进制文件。不知道这对你的情况是否重要。我认为你需要提供关于如何“运行”这个程序的详细信息,以及
    进程的作用。我尝试了一个文本文件,没有什么不同。我刚刚添加了请求的详细信息。为什么不按顺序将输入分发到文件中(因为您正在这样做,只是通过锁定),然后并行处理这些文件?另外:
    读取顺序
    @tfb感谢建议的解决方法。如果我这样做,而我的输入文件是X兆字节,我将需要2*X的磁盘空间来进行处理。我可能没有那么多。