2013-05-03 28 views
5

Tôi đã có quy trình con chỉ với exit(0). Nó đã trở thành zombie. Có cách nào để xóa nó mà không cần wait hoặc waitpid trong quy trình gốc không?quá trình xóa mà không cần chờ đợi C

R+ ./server //parent 
R+ ./server //child 
Z+ (server) //child zombie 
+0

Không chắc chắn đây là bài đăng C. Có lẽ vì Unix đã được tạo ra trong C? :) –

+0

Tại sao bạn không muốn sử dụng 'wait' hoặc' waitpid'? – FDinoff

+0

vì 'wait' sẽ dừng quá trình cha mẹ, cho đến khi thoát. –

Trả lời

5

đơn giản nhất là làm cho SIGCHLD bỏ qua trong các phụ huynh:

signal(SIGCHLD, SIG_IGN); 

Sau đó, thoát khỏi tiến trình con sẽ chỉ sạch đi xa mà không cần phải được chờ đợi trên.

Lưu ý: Đây là một cách nhanh chóng & cách tiếp cận không hợp lệ và giả định rằng bạn không quan tâm đến trạng thái thoát của quá trình con hoặc về thời điểm thoát. Nếu bạn quan tâm, như bạn có lẽ nên trong một ứng dụng thực sự mạnh mẽ, sau đó xem câu trả lời khác, về việc tạo ra một chức năng xử lý tín hiệu thích hợp.

Bổ sung: Tính năng này không phổ biến trong Unix, nhưng hoạt động ít nhất trên Linux. Theo an UNIX FAQ, đó là hành vi không xác định trong POSIX. This Mac OS X man page cho thấy rằng hành vi này đã được giới thiệu trong FreeBSD 5.0 ​​và hoạt động trên OS X chẳng hạn.

+1

Các quy trình con không biến mất (không bị zombie) chỉ khi quá trình gốc thoát ra? Nói cách khác, chúng không phải là zombie cho đến khi bố mẹ thoát ra sao? Tôi sẽ tưởng tượng các phụ huynh vẫn có thể 'waitpid' họ ngay cả khi bỏ qua tín hiệu 'SIGCHLD', do đó hạt nhân phải zombify quá trình trẻ em (nhưng tôi có thể sai, bởi vì tôi đã không kiểm tra đó). –

+0

@BasileStarynkevitch Đã thêm đoạn văn và liên kết giải thích thêm. Nhưng khi nó hoạt động, sau đó thoát/chấm dứt quá trình con thực sự chỉ biến mất, không có zombie, không thể chờ đợi. – hyde

+0

Nhưng quá trình con có biến mất ngay lập tức hay chỉ khi quá trình gốc thoát ra? –

6

Bạn có thể bắt SIGCHLD tín hiệu (ví dụ sử dụng sigaction(2) vv ...). Hãy cẩn thận, rất ít chức năng được gọi một cách an toàn từ bộ xử lý tín hiệu. Đọc nhiều lần signal(7) & signal-safety(7). Một điều tốt để thực hiện bên trong trình xử lý tín hiệu là chỉ cần đặt một số cờ volatile sigatomic_t (mà bạn sẽ kiểm tra sau, bên ngoài của trình xử lý tín hiệu, ví dụ: trong một số event loop). Hoặc bạn có thể, tại thời điểm khởi tạo, thiết lập một pipe(7) (với quy trình của riêng bạn) và viết một vài byte vào nó trong trình xử lý tín hiệu của bạn (và poll(2) đầu đọc ở nơi khác), như suggested by Qt.

waitpid(2) có thể được nói đến không chỉ dừng lại ở WNOHANG

Nếu bạn không bao giờ chờ đợi cho quá trình con bạn, nó sẽ trở thành zombie.

Đọc Advanced Linux Programming. Nó có một chương tốt về quy trình.

2

Bạn có thể sử dụng đôi fork kỹ thuật:

Tạo một quá trình con trẻ. Và chấm dứt quá trình con ngay lập tức sau đó. Bằng cách này, quy trình con của trẻ sẽ được thực hiện theo quy trình init. Quá trình init sẽ tự động chờ đợi quá trình con của trẻ khi thoát.

Điều này không xóa waitpid, bởi vì phụ huynh phải chờ kết thúc quá trình con. Bởi vì thời gian cuộc sống của quá trình con luôn luôn là tối thiểu, bạn có thể gọi waitpid từ cha mẹ mà không bị chặn dài.

Xem this article để biết thêm thông tin.

Các vấn đề liên quan