2012-02-09 31 views
6

Tôi đã phát hiện ra Perl forking và tôi khá trong tình yêu. Nhưng có một điều liên quan đến tôi - nếu tôi chỉ tách các quy trình trái và phải, chắc chắn điều này sẽ gây ra một số vấn đề ở đâu đó. Có một loại kiểm tra hợp lý mà người ta nên sử dụng để đảm bảo rằng ứng dụng nhỏ của tôi không ăn hết tất cả các tài nguyên của máy của tôi?Perl - chịu trách nhiệm forking

Lấy mẫu này mã:

foreach my $command (@commands) { 
    my $pid = fork(); 
    if (!$defined $pid) { 
    #Fork failed. Do something. 
    } elsif ($pid == 0) { #This is the child. 
     system($command); 
     exit(0) 
    } 
} 

while (wait() != -1) {} #wait() will be -1 when the last child exits. 

Vì vậy, đây sẽ làm việc tốt, và đẻ trứng ra một quy trình để xử lý mỗi lệnh. Tất cả sẽ xảy ra song song, điều tuyệt vời nếu các lệnh này hoàn toàn độc lập.

Nếu tôi đột nhiên có hơn 5.000 lệnh để chạy qua thì sao? Nó sẽ không được khôn ngoan để vô tư ngã ba mà nhiều quá trình. Vì vậy, loại kiểm tra nên được thực hiện, và làm thế nào?

)

+1

Um, theo dõi có bao nhiêu bạn đã chia hai, và dừng lại ở một max vì vậy bạn không giết máy và có một sớm để được sysadmin rất giận dữ thức dậy lúc 3 giờ sáng? ;) –

+0

Được rồi, nhưng "tối đa" hợp lý là gì? – Jeremy

+2

Thật ngớ ngẩn khi gọi 'hệ thống' ở nơi bạn đã làm. 'system' về cơ bản là' fork' + 'exec' (child) +' waitpid' (parent). Thay đổi 'system' thành' exec'. – ikegami

Trả lời

7

Ngoài ra nếu bạn đang lo lắng về sinh sản quá nhiều quá trình chia hai cùng một lúc, bạn có thể tăng tốc cho họ.

Hoặc cuộn của riêng bạn (sử dụng hàng đợi để giữ "ngã ba"), hoặc tốt hơn, sử dụng mô-đun Parallel::ForkManager cho phép bạn giới hạn các dĩa đồng thời thông qua tham số hàm tạo.

use Parallel::ForkManager; 
$pm = new Parallel::ForkManager($MAX_PROCESSES); 

Xin lưu ý rằng ForkManager sẽ CŨNG chăm sóc gặt hái tiến trình con kết thúc cho bạn thông qua một cung cấp "chờ *" API

+0

Điều này nghe có vẻ giống như con đường để đi! Cảm ơn. – Jeremy

3

Khi một đứa trẻ ra khỏi nó sẽ gửi lại một SIG_CHLD cho phụ huynh. Bạn sẽ muốn gặt hái những thứ như thể bạn không phải là zombie trong bảng xử lý cho đến khi cuộc gọi cuối cùng đó đến số wait ở cuối tập lệnh của bạn.

Chapter 16 of O'Reilly's Perl Cookbook on Google books cung cấp một loạt thông tin về điều này. Về cơ bản, bạn cần phải tăng số lượt truy cập khi bạn đang tìm kiếm trẻ em, và giảm nó khi bạn đang gặt hái chúng, và không phải ngã ba mới qua một tối đa hợp lý của trẻ em hiện đang chạy.

Đối với những gì "tối đa hợp lý" là ... phụ thuộc vào phần cứng và những quy trình được chia đôi đó đang làm gì. Không có câu trả lời tĩnh cho câu hỏi đó ngoài việc nói kiểm tra những gì bạn đang làm và nhìn vào tác động hiệu suất trên máy. Tốt nhất là trong giờ làm việc. Sau khi nói với sysadmin những gì bạn đang làm. Anh/cô ấy thậm chí có thể có một số lời khuyên.

+0

Không liên kết đến việc sao chép trái phép tài liệu có bản quyền. –

+1

Ok, tôi sẽ liên kết đến chính xác điều tương tự trên sách của Google. –

1

Để chắc chắn bạn không đẻ trứng quá trình nhiều hơn những gì hệ thống một cách hiệu quả có thể xử lý, bạn có thể sử dụng mô-đun như Parallel::ForkManager

0

Spawning (forking) như nhiều quá trình như hệ thống của bạn có thể hỗ trợ được gọi là một fork bomb. Hệ thống của bạn có thể bị đóng băng hoặc hỏng khi bảng xử lý của nó trở nên bão hòa và bộ nhớ và CPU bị cạn kiệt. Trên các hệ thống Linux, lệnh ulimit sẽ hiển thị số lượng quy trình người dùng tối đa được phép. Bạn có thể (nên) thiết lập này một cách thích hợp cho hệ thống của bạn. Việc chia nhánh tạo ra các quy trình theo cấp số nhân. Như vậy, đoạn này tạo ra bốn quá trình vô tận tiêu thụ CPU cho đến khi chết --- một khó chịu, quả bom nhỏ:

perl -e 'fork; fork; 1 while {}' 
Các vấn đề liên quan