Cách hiệu quả để sử dụng tất cả các lõi trong tập lệnh bash hoặc zsh


6

Nếu tôi muốn xử lý số lượng lớn tệp bằng lệnh "do_s Something" chỉ có thể sử dụng một lõi, cách tốt nhất để sử dụng tất cả các lõi có sẵn giả sử mỗi tệp có thể được xử lý độc lập?

Tại thời điểm này tôi làm một cái gì đó như thế này:

#!/bin/zsh
TASK_LIMIT=8
TASKS=0
for i in *(.)
{
  do_something "$i"&
  TASKS=$(($TASKS+1))
  if [[ $TASKS -ge $TASK_LIMIT ]]; then
    wait; TASKS=0; fi
}
wait

Rõ ràng, điều này không hiệu quả vì sau khi đạt $ TASK_LIMIT, nó sẽ đợi khi tất cả "do_s Something" kết thúc. Ví dụ, trong tập lệnh thực của tôi, tôi sử dụng khoảng 500% CPU 8 lõi thay vì> 700%.

Chạy mà không có $ TASK_LIMIT không phải là một tùy chọn vì "do_s Something" có thể tiêu tốn nhiều bộ nhớ.

Lý tưởng nhất là tập lệnh nên cố gắng giữ số lượng tác vụ song song ở mức $ TASK_LIMIT: ví dụ: nếu tác vụ 1 trên 8 kết thúc và có ít nhất một tệp nữa để xử lý, tập lệnh sẽ chạy "do_s Something" tiếp theo thay vì chờ 7 tác vụ còn lại kêt thuc. Có cách nào để đạt được điều này trong zsh hoặc bash không?


gợi ý: sử dụng trapđể bắt SIGCHLD ở chế độ màn hình.
Keith

Câu trả lời:


6

Tôi thực sự khuyên bạn nên xem xét song song GNU . Nó thực hiện chính xác những gì bạn muốn và không phụ thuộc vào bất kỳ vỏ cụ thể nào.


0

Hãy nhớ có bao nhiêu quá trình bạn bắt đầu. Khi một quá trình kết thúc, giảm số lượng. Khi số lượng thấp hơn mức tối đa, bắt đầu một quy trình mới.

Vấn đề duy nhất là làm thế nào để báo hiệu sự kết thúc của một quá trình. Ví dụ, bạn có thể tạo một tệp emty của một tên đã cho trong / tmp (bao gồm $$ và $ BASHPID).

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.