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))))

(mkfifo を使用して) FIFO を作成し、ファイルをそこにコピーして、代わりにそれを使用してプログラムを実行すると、再び並列処理が観察されます。

上記のプログラムは、ECL を使用してコマンド ライン ユーティリティとしてビルドされ、Linux で実行されます。次のいずれかの方法で実行します。

  1. 猫「ビッグファイル」 | マイプログラム
  2. 私のプログラム「ビッグファイル」

並列処理はケース 2 でのみ発生します。

問題は、なぜ違いがあるのか​​ということです。

アップデート:

  • 私の質問に間違いがありました。これでOKです。
  • process関数を追加し、プログラムの実行方法を説明しました
4

0 に答える 0