Mô hình phân phối xác suất điều kiện cuộc đua này là gì?


10

Hãy xem xét các lệnh sau : bash -c "echo x; cat 1" | tee 1.

Sự hiểu biết của tôi là nó sẽ rẽ nhánh sang một shell mới, ghi xvào thiết bị xuất chuẩn , viết cho thiết bị xuất file 1 not foundchuẩn, thoát và trả lại quyền điều khiển cho tiến trình cha, và viết xcho thiết bị xuất chuẩn và chuyển đổi 1. Do đó, tôi mong đợi kết quả đầu ra cuối cùng xvà tệp 1chứa chính xác chuỗi x.

Tuy nhiên, đây không phải là trường hợp. Trong thực tế, tệp 1thường chứa ít nhất hai trường hợp xvà đôi khi hàng nghìn dòng xs. Trong một bài kiểm tra hàng loạt về việc chạy lệnh mười nghìn lần, số xs trung bình được ghi vào tệp là 52,3 và trung vị là 1. Cơ chế nào gây ra điều này? Mô hình phân phối xác suất nào hành vi này? Tôi nghi ngờ rằng nó là hình học có điều kiện và thống nhất.


3
Nó phải làm với thời gian thực hiện phía bên trái và bên phải của đường ống. Cả hai được bắt đầu đồng thời, hoặc gần với nó. Nếu teeđã mở tệp để viết trước khi catmở tệp để đọc, bạn có thể nhận được nhiều x-es trong tệp. Trong trường hợp đó, "vòng lặp" sẽ kết thúc bất cứ khi nào catđọc nhanh hơn teeghi, đến cuối tệp.
Kusalananda

Từ thử nghiệm hạn chế ở đây, số xs trung bình được ghi vào tệp là 4,35. Tôi đoán nó sẽ phụ thuộc rất nhiều vào tải máy.
Renan

Câu trả lời:


1

Đây là một điều rất tò mò, vì vậy tôi đã cố gắng điều tra nó với sự giúp đỡ của strace. Chạy lệnh của bạn trong một vòng lặp 1000 lần:

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

Tìm thấy tệp có hầu hết các dòng ( wc -l */1 | sort -nr | head -n2) và kiểm tra tương ứng trace.log. Tôi chắc chắn có thể thấy rất nhiều:

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

Trong đó 7567 là tee 1và 7568 là cat 1. Cả hai chắc chắn là xen kẽ, vì vậy, như nghi ngờ, đây là tất cả về thời gian thực hiện (và tôi tưởng tượng chuyển đổi ngữ cảnh) của hai lệnh.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.