0

我有一个 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 上运行。我以下列方式之一运行它:

  1. 猫“大文件”| 我的程序
  2. 我的程序“大文件”

并行性仅在情况 2 中发生。

问题是为什么会有差异?

更新:

  • 我的问题有误。现在可以了。
  • 添加了process功能并描述了我如何运行程序
4

0 回答 0