Ai đó có thể cho tôi biết cách đốt cháy và quên một quy trình trong Perl không? Tôi đã xem ruby: how to fire and forget a subprocess? để làm điều tương tự trong Ruby.Làm sao tôi có thể bắn và quên một tiến trình trong Perl?
Trả lời
Từ câu trả lời perlfaq8 's để How do I start a process in the background?
Một số module có thể bắt đầu quá trình khác mà không chặn chương trình Perl của bạn. Bạn có thể sử dụng IPC :: Open3, Parallel :: Jobs, IPC :: Run và một số mô-đun POE . Xem CPAN để biết thêm chi tiết.
Bạn cũng có thể sử dụng
system("cmd &")
hoặc bạn có thể sử dụng nĩa như tài liệu trong "ngã ba" trong perlfunc, với thêm ví dụ trong perlipc. Một số điều cần phải nhận thức được, nếu bạn đang ở trên một Unix- như hệ thống:
STDIN, STDOUT, và stderr được chia sẻ
Cả hai quá trình chính và một background (những "đứa trẻ" quy trình) chia sẻ cùng một tệp STDIN, STDOUT và STDERR. Nếu cả hai cố gắng truy cập chúng cùng một lúc, những điều kỳ lạ có thể xảy ra. Bạn có thể muốn đóng hoặc mở lại chúng cho trẻ. Bạn có thể nhận được xung quanh điều này với "mở" ing một đường ống (xem "mở" trong perlfunc) nhưng trên một số hệ thống này có nghĩa là quá trình con không thể sống lâu hơn phụ huynh .
Tín hiệu
Bạn sẽ phải nắm bắt những tín hiệu SIGCHLD, và có thể SIGPIPE quá. SIGCHLD được gửi khi quá trình nền kết thúc. SIGPIPE là được gửi khi bạn viết thư cho người nộp hồ sơ có quá trình con đã đóng (một SIGPIPE chưa được khai báo có thể khiến chương trình của bạn âm thầm chết). Đây không phải là vấn đề với "hệ thống (" cmd & ")".
Zombies
Bạn cần phải được chuẩn bị để "gặt hái" quá trình đứa trẻ khi nó kết thúc.
$SIG{CHLD} = sub { wait };
$SIG{CHLD} = 'IGNORE';
Bạn cũng có thể sử dụng một ngã ba đôi. Bạn ngay lập tức chờ đợi() cho con đầu tiên của bạn và daemon init sẽ đợi() cho cháu của bạn khi nó thoát.
unless ($pid = fork) {
unless (fork) {
exec "what you really wanna do";
die "exec failed!";
}
exit 0;
}
waitpid($pid, 0);
Xem "Tín hiệu" trong perlipc để biết các ví dụ mã khác để thực hiện việc này. Zombies không phải là vấn đề với "hệ thống (" prog & ")".
Nếu bạn muốn daemonize kịch bản Perl của bạn tôi đã nhìn vào Proc::Daemon.
Thực ra, tôi không muốn sao chép nó, tôi chỉ cần khởi chạy tập lệnh cơ quan giám sát trong nền trong suốt thời gian thực thi tập lệnh chính của tôi. Và tôi chỉ có Perl 5.6.0 cơ bản để làm việc với, vì điều này đang thực thi trên một hệ thống nhúng với bộ nhớ bị hạn chế nghiêm trọng và tôi không có nhiều mô-đun để làm việc. –
Vâng, bạn không nên sử dụng system()
như tôi hiểu cuộc gọi này sẽ chờ đợi sự trở lại của các chức năng trước khi tiếp tục thực hiện. Tôi chỉ đơn giản là shell ra Linux và bắt đầu quá trình như vậy, mặc dù hãy ghi nhớ theo cách này sẽ envoke một bản sao mới của vỏ và vì vậy nếu bạn đang tìm kiếm hiệu suất tôi sẽ không làm điều này trong một vòng lặp ví dụ:
process_name > /dev/null 2>&1 &
;
Điều đó sẽ bắt đầu quá trình chuyển hướng STDOUT
và STDERR
đến /dev/null.
Nếu bạn muốn quá trình "con" giám sát bị biến mất khi quá trình "cha mẹ" thoát ra thì bạn không thực sự muốn quy trình cha mẹ "kích hoạt và quên" quá trình con. Bạn cần phải ngã ba (như được mô tả bởi brian d foy) hoặc chuyển PID của cha mẹ cho đứa trẻ (vì vậy sau này có thể thăm dò ý kiến của bảng tiến trình - không được khuyến nghị).
Trên thực tế, chạy kịch bản watchdog như là một quá trình con có lẽ là một ý tưởng tồi vì có lẽ cơ quan giám sát phải làm gì đó nếu kịch bản chính chết bất ngờ (nhưng nếu cha mẹ chết thì hãy làm tất cả các con của nó). Một cách khác để đi là có "quy trình chính" thiết lập một đường ống có tên và viết "nhịp tim" tin nhắn cho nó + thông báo "đã hoàn tất" khi thoát, trong khi cơ quan giám sát (khởi chạy ở chế độ "lửa và quên" thực sự qua system ("cmd &")) đọc từ các đường ống có tên và các thông báo khi một thông báo "đã hoàn thành" đến hoặc các thông báo "heartbeat" dừng lại. – Peter
- 1. Làm thế nào để bắn và quên một tiến trình con?
- 2. Tôi có thể hiển thị tiến trình sao chép tệp bằng FileInfo.CopyTo() trong .NET không?
- 3. Làm thế nào tôi có thể tạm thời dừng STDOUT trong một chương trình Perl?
- 4. Git Git của tôi quên bí danh của tôi. Tôi có thể làm gì?
- 5. Làm thế nào tôi có thể làm cho kịch bản Perl của tôi sử dụng nhiều lõi cho các tiến trình con?
- 6. Trong Perl, làm thế nào tôi có thể gọi một phương thức có tên tôi có trong một chuỗi?
- 7. Tôi quên mật khẩu chính Glassfish3, làm cách nào tôi có thể đặt lại mật khẩu?
- 8. Visual Studio có thể cảnh báo tôi khi tôi quên bỏ một đối tượng IDisposable không?
- 9. Tôi có thể làm gì khi sử dụng awk mà tôi không thể làm trong Perl?
- 10. Làm thế nào tôi có thể làm cho Perl chờ đợi cho các tiến trình con bắt đầu trong nền với hệ thống()?
- 11. Làm thế nào tôi có thể lấy tên của chương trình con hiện tại trong Perl?
- 12. Làm cách nào để tôi có thể trực tiếp các chương trình con Perl?
- 13. Làm thế nào tôi có thể sinh ra các tiến trình đồng thời với PHP?
- 14. Làm thế nào tôi có thể gọi một phương thức trong một cá thể tiến trình khác của ứng dụng WinForms của tôi?
- 15. Làm thế nào tôi có thể sử dụng một biến như một tên biến trong Perl?
- 16. Làm thế nào tôi có thể lưu trữ và truy cập một filehandle trong một lớp Perl?
- 17. Tôi có thể sử dụng Strawberry Perl và ActiveState Perl đồng thời trong một máy tính không?
- 18. Làm thế nào tôi có thể bắt đầu ra từ một con cá chép trong Perl?
- 19. Làm thế nào tôi có thể đoán mã hóa của một chuỗi trong Perl?
- 20. Làm thế nào tôi có thể trích xuất các chất nền từ một chuỗi trong Perl?
- 21. Làm thế nào tôi có thể lưu trữ ảnh chụp regex trong một mảng trong Perl?
- 22. Làm thế nào tôi có thể tìm thấy số lượng khóa trong một băm trong Perl?
- 23. Làm thế nào tôi có thể lặp qua nhiều danh sách cùng một lúc trong Perl?
- 24. Kịch bản Perl có thể sử dụng làm chương trình và làm mô-đun
- 25. C# Fire và Quên cuộc gọi bên trong một WebMethod
- 26. Làm thế nào tôi có thể sử dụng băm làm đối số cho các chương trình con trong Perl?
- 27. Làm thế nào tôi có thể bọc một chuỗi trong Perl?
- 28. Làm thế nào tôi có thể ssh bên trong một kịch bản Perl?
- 29. Trong Perl, làm cách nào tôi có thể biết chuỗi là một số?
- 30. Làm thế nào tôi có thể in chỉ một dòng mới unix trong Perl trên Win32?
Cảm ơn bạn rất nhiều, tôi đã không nghĩ đến việc sử dụng toán tử vỏ nền trong lệnh. Điều đó đã làm các trick. Thật không may tôi không thể sử dụng những người khác bởi vì tôi đang làm việc trên một hệ thống bị hạn chế nghiêm trọng với hầu như không có mô-đun. –
Đúng vậy, nếu bạn đưa ra lệnh system() với '&' char nó trả về ngay lập tức, do đó phương thức toán tử back-tick mà tôi đã đề xuất không tốt lắm - tốt hơn để sử dụng cuộc gọi hệ thống của Perl thay vì gọi toàn bộ bản sao mới của trình bao. –