Cách chạy các quy trình song song và kết hợp đầu ra khi cả hai hoàn thành


17

Tôi có một tập lệnh bash shell trong đó tôi chuyển một số dữ liệu thông qua khoảng 5 hoặc 6 chương trình khác nhau sau đó kết quả cuối cùng thành một tệp được phân tách bằng tab.

Sau đó tôi làm lại tương tự cho một tập dữ liệu tương tự riêng biệt và xuất ra tệp thứ hai.

Sau đó cả hai tập tin được nhập vào một chương trình khác để phân tích so sánh. ví dụ để đơn giản hóa

Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv
AnalysisProg -i Data1res.csv Data2res.csv

Câu hỏi của tôi là: làm thế nào tôi có thể làm cho bước 1 và bước 2 chạy cùng một lúc (ví dụ: bằng cách sử dụng &) nhưng chỉ khởi chạy bước 3 (Phân tích) khi cả hai hoàn thành?

cám ơn

Phân tích ps sẽ không hoạt động trên một luồng hoặc fifo.



BTW, bạn có thể sử dụng tập lệnh Perl không? Điều này có thể đơn giản hóa vấn đề rất nhiều cho bạn và bạn có thể thực hiện việc xử lý hậu kỳ này rất hiệu quả và làm cho nó chạy song song dễ dàng.
Bíchoy

Perl..không quá nhiều, không :(
Stephen Henderson

1
Ở đây tôi trình bày cách phân chia đầu vào giữa các ống với teevà xử lý nó với hai grepquy trình đồng thời : unix.stackexchange.com/questions/120333/ trên
mikeerv

Và ở đây tôi trình bày cách sử dụng các cấu trúc shell đơn giản để hoàn toàn tạo nền cho một quy trình theo cách nohupcó thể nhưng vẫn duy trì một phương tiện giao tiếp với quy trình: unix.stackexchange.com/questions/121253/ trộm
mikeerv

Câu trả lời:


27

Sử dụng wait. Ví dụ:

Data1 ... > Data1Res.csv &
Data2 ... > Data2Res.csv &
wait
AnalysisProg

sẽ:

  • chạy các ống Data1 và Data2 làm công việc nền
  • đợi cả hai kết thúc
  • chạy Phân tíchProg.

Xem, ví dụ, câu hỏi này .


Thx, có vẻ tốt. Tôi sẽ thử điều này nếu những điều trên không hoạt động.
Stephen Henderson

Thx một lần nữa, tôi đã nhận thức được sự chờ đợi nhưng đã googled một chút đã bối rối với cách nó hoạt động với các bộ vi xử lý khác nhau, v.v. Tôi cảm thấy bây giờ tôi thấy nó chỉ là "chờ đợi"
Stephen Henderson

12

Câu trả lời của cxw chắc chắn là giải pháp thích hợp hơn, nếu bạn chỉ có 2 tệp. Nếu 2 tệp chỉ là ví dụ và trong thực tế bạn có 10000 tệp, thì giải pháp '&' sẽ không hoạt động, vì điều đó sẽ làm quá tải máy chủ của bạn. Cho rằng bạn cần một công cụ như GNU Parallel:

ls Data* | parallel 'cat {} | this | that |theother | grep |sed | awk |whatever > {}res.csv
AnalysisProg -i *res.csv

Để tìm hiểu thêm về GNU Parallel:


Chào thx. Tại thời điểm này tôi có hai tệp, nhưng tôi có 24 bộ xử lý nên tôi cảm thấy muốn thử và chạy nhiều cặp cùng một lúc - mặc dù không phải là một người làm khoa học máy tính. có lẽ tôi sẽ mút nó và xem;)
Stephen Henderson

@StephenHenderson tùy thuộc vào kích thước, các tệp vẫn có thể nằm trong bộ đệm. Nếu tốc độ là quan trọng, bạn chỉ có thể sử dụng tmpfs (và các tệp là <<< thì RAM của bạn).
Maciej Piechotka

1
@StephenHenderson Số lượng công việc song song có thể được điều chỉnh bằng -j, vì vậy hãy thử -j4 và nếu máy chủ không quá tải, hãy thử -j6, v.v. Nhưng hãy sẵn sàng nhấn CTRL-C: GNU Parallel là một công cụ tuyệt vời để tải quá nhanh máy chủ . Cũng có một cái nhìn tại - tải.
Ole Tange

1

Một cách để làm điều này có thể trông giống như:

AnalysisProg <<PREPROCESS /dev/stdin
$( 
{   process1=$( pipe | line | 1 >&2 & echo $! )
    process2=$( pipe | line | 2 >&2 & echo $! )
    while ps -p $process1 $process2 >/dev/null; do
        sleep 1
    done
} 2>&1
)
#END
PREPROCESS

Theo cách này, bạn làm nền cho cả hai đường ống nhưng vẫn đợi chúng hoàn thành việc thực thi trước khi kết hợp đầu ra của chúng thành stdin, được đánh giá trong tài liệu ở đây và trao cho Phân tích. Nếu bạn có thể sử dụng waitđiều này thậm chí còn tốt hơn while psvòng lặp, nhưng, tùy thuộc vào shell, waitcó thể phản đối nếu bạn hướng dẫn nó chờ xung quanh trên một quy trình không phải là con của shell hiện tại.

Cũng lưu ý rằng phương pháp trên sẽ đối chiếu đầu ra - vì vậy cả hai quá trình sẽ được viết ra cùng một lúc. Thay vào đó, nếu bạn muốn tách chúng ra, hoặc nối thêm cái này với cái khác có thể bạn có thể làm:

AnalysisProg 3<<PREPROCESS /dev/fd/3 /dev/stderr
$(
process1=$(... >&2 ...) 2>/dev/fd/3
...
} 3>/dev/fd/3 2>/dev/stderr
)

Tôi đã chứng minh những khái niệm này trước đây. Có lẽ các bản demo tốt nhất đang ở đâyđây .


0

Hãy thử sử dụng cái này.

rm -f Data1Res.csv
rm -f Data2Res.csv
Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv &
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv &
while true
do
  ps aux | grep -v grep | grep -i -E 'Data1Res.csv|Data2Res.csv' &> /dev/null
  if [ $? -ne 0 ]
  then
    AnalysisProg -i Data1res.csv Data2res.csv
    exit 0
  fi
done

Vâng, đó là một nặng. Nó không giống như phát minh lại waitbánh xe?
John WH Smith
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.