Làm cách nào tôi có thể giết tiến trình <defposed> có cha mẹ là init?


27

Truyền được treo liên tục trên NAS của tôi. Nếu tôi gửi SIGTERM, nó sẽ không biến mất khỏi danh sách quy trình và một <defunct>nhãn xuất hiện bên cạnh nó. Nếu tôi gửi SIGKILL, nó vẫn không biến mất và tôi không thể chấm dứt cha mẹ vì cha mẹ là init. Cách duy nhất tôi có thể thoát khỏi quá trình và khởi động lại Transmission là khởi động lại.

Tôi nhận ra điều tốt nhất tôi có thể làm là thử và sửa chữa Transmission (và tôi đã thử), nhưng tôi là người mới trong việc biên dịch và tôi muốn chắc chắn rằng các torrent của tôi đã kết thúc trước khi tôi bắt đầu loay hoay với nó.


3
Không ai nói rõ ... một quy trình <defposed> thuộc sở hữu của "init" là không thể! Đây là một tình huống rất kỳ lạ! Bạn có chắc không?
JoelFan

@JoelFan: Tôi chỉ nhìn lên để chắc chắn rằng tôi đã không quên điều gì quan trọng. Thây ma là trẻ em initnên ra đi khá nhanh kể từ khi initchờ đợi trẻ em định kỳ là một trong nhiều nhiệm vụ phổ biến của nó ... có <defunct>giống như zombie không?
D.Shawley

1
Nevermind ... <defunct>chính xác giống như một thây ma. initsẽ chờ đợi con cái của nó vì vậy điều này không bao giờ nên xảy ra trong lý thuyết. Tôi tự hỏi điều gì xảy ra nếu bạn gửi SIGCHLDđến init?
D.Shawley

@JoelFan: vâng, tôi chắc chắn. Giá trị cho PPID là 1 (init), vì vậy không thể SIGKILL quá trình.
Andy E

Câu trả lời:


35

Bạn không thể giết một <defunct>tiến trình (còn được gọi là tiến trình zombie) vì nó đã chết. Hệ thống giữ các tiến trình zombie để cha mẹ thu thập trạng thái thoát. Nếu cha mẹ không thu thập trạng thái thoát thì các quá trình zombie sẽ tồn tại mãi mãi. Cách duy nhất để thoát khỏi những quá trình zombie đó là giết cha mẹ. Nếu cha mẹ là init thì bạn chỉ có thể khởi động lại.

Quá trình zombie chiếm gần như không có nguồn lực, do đó không có chi phí hiệu suất trong việc để chúng nán lại. Mặc dù có quá trình zombie xung quanh thường có nghĩa là có một lỗi trong một số chương trình của bạn. Ban đầu thường nên thu thập tất cả trẻ em. Nếu init có con zombie thì có lỗi trong init (hoặc một số khác nhưng đó là lỗi).

http://en.wikipedia.org/wiki/Zombie_ process


9
initkhông bao giờ có thể có con zombie. Từ bài viết trên wikipedia: Khi một tiến trình mất cha mẹ, init trở thành cha mẹ mới của nó. Ban đầu định kỳ thực hiện lệnh gọi hệ thống chờ để gặt hái bất kỳ zombie nào với init là cha. Một trong initnhững trách nhiệm của họ là gặt hái những đứa trẻ mồ côi và những thây ma không cha mẹ.
D.Shawley

14
@ D.Shawley: initcó thể có lỗi mặc dù. Việc thay thế init runitđã có một lỗi gây ra vấn đề này.
camh

2
init có thể có con không còn tồn tại, có thể do lỗi, nhưng có thể. Bởi vì tôi đang nhìn vào một cái ngay bây giờ.
studgeek

Có chương trình này mà tôi đã chạy từ thiết bị đầu cuối và chuyển sang trạng thái không còn tồn tại .. Như được giải thích bởi @lesmana, khi tôi đóng thiết bị đầu cuối (phụ huynh), chương trình đã thoát sạch.
mk ..

6

Bất cứ ai đang cố gắng sửa mã nguồn Transmission C nên đọc về thủ thuật "fork đôi" để tránh zombie và trình xử lý tín hiệu ... và làm thế nào nó có thể được sử dụng như một phần của chức năng sinh sản thông minh (xem Spawning trong Unix ).

excerpt from: 
   "Spawning in Unix", http://lubutu.com/code/spawning-in-unix

Double fork
This trick lets you spawn processes whilst avoiding zombies, without 
installing any signal handler. The first process forks and waits for its 
child; the second process forks and immediately exits and is reaped;
the third process is adopted by init, and executes the desired program. 
All zombies accounted for, since init is always waiting.

if(fork() == 0) {
   if(fork() == 0) {
       execvp(file, argv);
       exit(EXIT_FAILURE);
   }
   exit(EXIT_SUCCESS);
}
wait(NULL);

1
Nĩa đôi ngăn chặn các quá trình zombie bằng cách buộc kernel đặt cha mẹ của nó thành PID 1, được cho là để dọn sạch zombie. Nghe có vẻ như Transmission đã làm điều đó, vì cha mẹ của nó đã xử lý 1.
Jander

1
Có nhiều vấn đề ở đây. # 1: Chỉ cha mẹ nên gọi exit(3); trẻ em nên gọi _exit(2)thay thế (nếu không bạn nhận được nhiều cơn bốc hỏa, trong số các vấn đề khác). # 2: Điều đó execvp(3)có thể sử dụng perror(3)nếu nó thất bại. # 3: Bạn chỉ nên sử dụng signal(SIGCHLD, SIG_IGN)thay vì toàn bộ mớ hỗn độn này.
Kevin
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.