この競合状態をモデル化する確率分布は何ですか?


10

次のコマンドを検討してください bash -c "echo x; cat 1" | tee 1

私の理解では、新しいシェルにフォークし、xstdoutに書き込みfile 1 not found、stderrに書き込み、終了して親プロセスに制御を返し、xstdoutとtoに書き込み1ます。したがって、私は最終的な出力がであることを期待しx、ファイル1には文字列が正確に含まれますx

ただし、これは当てはまりません。実際には、ファイルに1は通常、の少なくとも2つのインスタンスが含まれx、時には数千行のxs が含まれます。コマンドを1万回実行するバッチテストでx、ファイルに書き込まれたsの平均数は52.3で、中央値は1でした。これを引き起こしているメカニズムは何ですか。この動作をモデル化する確率分布は何ですか?私はそれが条件付きで幾何学的で、それ以外は均一であると思います。


3
これは、パイプラインの左側と右側の実行のタイミングに関係しています。両方が同時に開始されるか、それに近い。読み取り用teecat開く前に書き込み用にファイルを開いた場合、ファイルに多くのx-esが表示されることがあります。その場合、「ループ」は書き込みcatよりも読み取りが速くなると必ずtee終了し、ファイルの最後に到達します。
クサラナンダ

ここでの限られたテストxから、ファイルに書き込まれたの平均数は4.35でした。それはマシンの負荷に大きく依存すると思います。
Renan

回答:


1

これは非常に興味深いものなので、straceを使用して調査しようとしました。コマンドをループで1000回実行しました。

mkdir {000..999}
for i in {000..999}; do
echo $i
(cd $i; strace -f -o trace.log bash -c 'bash -c "echo x; cat 1" | tee 1 >/dev/null'; )
done

最も多くの行(wc -l */1 | sort -nr | head -n2)を持つファイルを見つけ、対応するを確認しましたtrace.log。私は確かにたくさんを見ることができます:

7567  <... read resumed> "x\n", 8192)   = 2
7567  write(1, "x\n", 2)                = 2
7567  write(3, "x\n", 2)                = 2
7567  read(0,  <unfinished ...>
7568  read(3, "x\n", 131072)            = 2
7568  write(1, "x\n", 2)                = 2
7567  <... read resumed> "x\n", 8192)   = 2
7567  write(1, "x\n", 2)                = 2
7567  write(3, "x\n", 2)                = 2
7567  read(0,  <unfinished ...>
7568  read(3, "x\n", 131072)            = 2
7568  write(1, "x\n", 2)                = 2
7567  <... read resumed> "x\n", 8192)   = 2
7567  write(1, "x\n", 2)                = 2
7567  write(3, "x\n", 2)                = 2
7567  read(0,  <unfinished ...>

7567はtee 17568ですcat 1。2つは確実に交互に入れ替わるので、そうです、疑いがあるように、これはすべて2つのコマンドの実行のタイミング(そして私はコンテキストの切り替えを想像しています)に関するものです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.