Tôi có một nhiệm vụ xử lý một danh sách các tập tin trên stdin. Thời gian khởi động của chương trình là đáng kể và lượng thời gian mỗi tệp sẽ thay đổi rất nhiều. Tôi muốn sinh ra một số lượng đáng kể các quy trình này, sau đó gửi công việc tới bất kỳ nơi nào không bận rộn. Có một số công cụ dòng lệnh khác nhau gần như làm những gì tôi muốn, tôi đã thu hẹp nó thành hai tùy chọn gần như hoạt động:
find . -type f | split -n r/24 -u --filter="myjob"
find . -type f | parallel --pipe -u -l 1 myjob
Vấn đề là split
thực hiện một vòng tròn thuần túy, vì vậy một trong các quy trình bị tụt lại phía sau và ở lại phía sau, trì hoãn việc hoàn thành toàn bộ hoạt động; trong khi parallel
muốn sinh ra một quy trình cho mỗi N dòng hoặc byte đầu vào và tôi sẽ dành quá nhiều thời gian cho việc khởi động.
Có một cái gì đó như thế này sẽ sử dụng lại các quy trình và dòng cấp dữ liệu cho bất kỳ quy trình nào đã bỏ chặn các tiêu chuẩn?
myjob
đã sẵn sàng để nhận thêm đầu vào. Không có cách nào để biết rằng một chương trình đã sẵn sàng để xử lý nhiều đầu vào hơn, tất cả những gì bạn có thể biết là một số bộ đệm ở đâu đó (bộ đệm ống, bộ đệm stdio) đã sẵn sàng để nhận thêm đầu vào. Bạn có thể sắp xếp để chương trình của bạn gửi một số loại yêu cầu (ví dụ: hiển thị lời nhắc) khi nó sẵn sàng không?
read
các cuộc gọi sẽ thực hiện thủ thuật. Đó là một nỗ lực lập trình khá lớn.
-l 1
trong các đối số parallel
? IIRC, cho biết song song để xử lý một dòng đầu vào cho mỗi công việc (nghĩa là một tên tệp cho mỗi ngã ba của myjob, vì vậy rất nhiều chi phí khởi động).
split
Lệnh đó đến từ đâu? Tên xung đột với tiện ích xử lý văn bản tiêu chuẩn .