Khi nào tôi không nên giết -9 một quá trình?


401

Tôi luôn rất do dự để chạy kill -9, nhưng tôi thấy các quản trị viên khác làm việc đó gần như thường xuyên.

Tôi nghĩ có lẽ có một khu vực giữa hợp lý, vì vậy:

  1. Khi nào và tại sao nên kill -9được sử dụng? Khi nào và tại sao không?
  2. Những gì nên được thử trước khi làm điều đó?
  3. Loại gỡ lỗi nào của quy trình "treo" có thể gây ra thêm vấn đề?

Câu trả lời:


362

Nói chung, bạn nên sử dụng kill(viết tắt kill -s TERMhoặc trên hầu hết các hệ thống kill -15) trước kill -9( kill -s KILL) để tạo cơ hội cho mục tiêu dọn dẹp sau đó. (Các quy trình không thể bắt hoặc bỏ qua SIGKILL, nhưng chúng có thể và thường bắt được SIGTERM.) Nếu bạn không cho quá trình cơ hội hoàn thành những gì nó đang làm và dọn sạch, nó có thể để lại các tệp bị hỏng (hoặc trạng thái khác) xung quanh nó sẽ không thể hiểu được khi khởi động lại.

strace/ truss, ltracegdbnói chung là những ý tưởng tốt để xem xét lý do tại sao một quá trình bị mắc kẹt bị mắc kẹt. ( truss -utrên Solaris đặc biệt hữu ích; tôi thấy ltracequá thường xuyên đưa ra các đối số cho các cuộc gọi thư viện ở định dạng không sử dụng được.) Solaris cũng có /proccác công cụ dựa trên hữu ích , một số trong số đó đã được chuyển sang Linux. ( pstackthường hữu ích).


67
Lý do thuyết phục là nếu bạn có thói quen gửi SIGKILL, thì khi bạn đến một chương trình, ví dụ, sẽ làm hỏng một cơ sở dữ liệu quan trọng cho bạn hoặc công ty của bạn, bạn sẽ thực sự hối tiếc. kill -9có công dụng của nó, như là một kết thúc cuối cùng, nhấn mạnh vào cuối cùng; quản trị viên sử dụng nó trước lần cuối cùng a) không hiểu là quản trị viên quá tốt và b) không nên có trên hệ thống sản xuất.
Arcege

9
@Mikel Một điều khác thông qua nó, đôi khi tốt nhất là lừa một ứng dụng tự dọn dẹp bằng một tín hiệu như SIGQUIT hoặc SIGSEGV nếu nó không phản hồi với SIGINT / SIGTERM. Ví dụ: ứng dụng 3-D toàn màn hình hoặc thậm chí Xorg. Sử dụng SIGQUIT, nó sẽ không có cơ hội để dọn dẹp bất cứ thứ gì, nhưng lừa nó nghĩ rằng một lỗi phân khúc xảy ra và nó sẽ cảm thấy không có lựa chọn nào khác ngoài việc dọn dẹp và thoát ra.
chim cánh cụt359

12
@Arcege Bạn có nghĩ rằng việc sử dụng cơ sở dữ liệu làm hỏng dữ liệu nếu bị giết bằng -9 là cơ sở dữ liệu đáng để sử dụng không? iirc, mysql, bdb, pg, v.v ... tất cả đều hoạt động tốt khi bị giết với -9.
dhruvbird

13
killall -9 java ftw
dmourati

23
@dhruvbird: chỉ vì DB của bạn được trang bị áo chống đạn không có nghĩa là bạn nên bắn chúng nếu bạn không cần. Mặc dù bạn có thể đúng rằng nó không mạo hiểm như Arcege dường như nói, tôi nghĩ rằng quan điểm của ông vẫn cho rằng đó là rủi ro và nên là phương sách cuối cùng.
iconoclast

228

Randal Schwartz thường đăng bài "Sử dụng vô dụng (x)" trong danh sách. Một bài như vậy là về kill -9. Nó bao gồm các lý do và một công thức để làm theo. Đây là một phiên bản được xây dựng lại (trích dẫn dưới đây).

(Trích lời gớm ghiếc)

Không không không. Đừng dùng kill -9.

Nó không cho quá trình một cơ hội để làm sạch:

1) tắt kết nối ổ cắm

2) làm sạch các tập tin tạm thời

3) thông báo cho con của nó rằng nó sẽ biến mất

4) thiết lập lại các đặc điểm đầu cuối của nó

Vân vân và vân vân.

Nói chung, gửi 15, và đợi một hoặc hai giây, và nếu điều đó không hiệu quả, hãy gửi 2 và nếu điều đó không hiệu quả, hãy gửi 1. Nếu không, hãy BỎ L BIN B BINNG CÁCH vì chương trình hoạt động kém!

Đừng dùng kill -9. Đừng mang ra máy gặt đập liên hợp chỉ để dọn dẹp chậu hoa.

Chỉ cần sử dụng Usenet vô dụng khác,

(.Chữ ký)


12
Hệ điều hành sẽ đóng bất kỳ mô tả tệp mở nào (bao gồm cả ổ cắm) khi quá trình kết thúc?
Brian Gordon

3
Nó sẽ được thôi. Nhưng giả sử bạn đang giết một tiến trình máy chủ với các máy khách được kết nối, thì các máy khách sẽ không nhận thấy rằng máy chủ đã biến mất trước khi hết thời gian.
Bjorn Lindqvist

45
À đúng rồi, nếu nó không hoàn hảo thì bạn thật ngu ngốc khi sử dụng nó ".
Timmmm

3
Hoặc ngu ngốc khi sử dụng nếu quy trình được đề cập là sản phẩm của công ty bạn
Warren P

3
Nếu một tiến trình bị giết thì ổ cắm sẽ gửi RST tới thiết bị ngang hàng, trong đó nếu quá trình đó gọi đóng hoặc tắt trên ổ cắm, thì ổ cắm sẽ gửi FIN. Không có thời gian chờ cần thiết. Tình trạng hết thời gian sẽ chỉ xảy ra nếu mất điện hoặc rút cáp mạng.
ctrl-alt-delor

78

Nó sẽ luôn luôn ổn để làm kill -9, giống như nó luôn luôn ổn để tắt máy bằng cách kéo cáp nguồn. Nó có thể chống lại xã hội và để lại một số phục hồi để làm, nhưng nó phải hoạt động, và là một công cụ quyền lực cho những người thiếu kiên nhẫn.

Tôi nói điều này như một người sẽ thử tiêu diệt (15) trước, bởi vì nó cho chương trình một cơ hội để dọn dẹp - có lẽ chỉ cần viết vào một bản ghi "thoát trên sig 15". Nhưng tôi sẽ không chấp nhận bất kỳ khiếu nại nào về hành vi xấu đối với một vụ giết -9.

Lý do: nhiều khách hàng làm điều đó với những thứ mà các lập trình viên thích thì không. Thử nghiệm ngẫu nhiên -9 là một kịch bản thử nghiệm tốt và công bằng, và nếu hệ thống của bạn không xử lý nó, hệ thống của bạn sẽ bị hỏng.


2
Làm thế nào để bạn kiểm tra "giết ngẫu nhiên -9"? Khi bạn giết -9, bạn đã hoàn thành và kết thúc.
Karel Bílek

18
@Karel: Bạn kiểm tra xem hệ thống của bạn có thể phục hồi sau đó hay không và dọn sạch mọi giao dịch bị xử lý đang được xử lý tại thời điểm SIGKILL.
Tadeusz A. Kadłubowski

7
Nó không ổn để làm kill -9giống như nó không ổn để rút phích cắm ra. Trong khi tất nhiên có những tình huống mà bạn không có sự lựa chọn, đây nên là một hành động cuối cùng. Tất nhiên, kéo cáp điện hoặc kill -9không nên có tác dụng phụ như ngăn chặn các ứng dụng hoặc hệ điều hành để khởi động lại đúng nếu ở tất cả, nhưng đi tiêu xảy ra và sử dụng những cách được đề xuất ( kill [-15]) hoặc tắt máy thường xuyên sẽ giúp tránh sự lộn xộn có thể xảy ra nếu bạn thường xuyên làm gián đoạn các chương trình và hệ điều hành theo cách đó. Trong mọi trường hợp, luôn có nguy cơ mất dữ liệu bất kể độ mạnh của mã.
jlliagre

7
Tôi nghi ngờ ý của Michael là 'OK' là chương trình của bạn sẽ xử lý tình huống này một cách duyên dáng và có thể thực hiện một số hình thức dọn dẹp khi khởi động lại. Ví dụ, làm sạch các tệp PID và vv, thay vì chỉ ném đồ chơi của nó ra khỏi xe và từ chối bắt đầu.
gerryk

2
@gerryk Họ thực sự nên nhưng vấn đề là một số người sẽ coi câu trả lời đó là "giấy phép giết -9" bất kể tình huống và môi trường. Đó là một thái độ vô trách nhiệm.
jlliagre

39

Tôi sử dụng kill -9 theo cách tương tự như cách tôi ném dụng cụ nhà bếp vào máy rửa chén: nếu việc thực hiện nhà bếp bị phá hỏng bởi máy rửa chén thì tôi không muốn điều đó.

Điều tương tự cũng xảy ra với hầu hết các chương trình (thậm chí cả cơ sở dữ liệu): nếu tôi không thể giết chúng mà không gặp sự cố, tôi không thực sự muốn sử dụng chúng. (Và nếu bạn tình cờ sử dụng một trong những cơ sở dữ liệu không khuyến khích bạn giả vờ rằng họ đã lưu giữ dữ liệu khi họ không có: tốt, tôi đoán rằng đã đến lúc bạn bắt đầu nghĩ về những gì bạn đang làm).

Bởi vì trong thế giới thực, mọi thứ có thể đi xuống bất cứ lúc nào vì bất kỳ lý do gì.

Mọi người nên viết phần mềm chịu được sự cố. Đặc biệt trên các máy chủ. Bạn nên học cách thiết kế phần mềm giả định rằng mọi thứ sẽ bị hỏng, sụp đổ, v.v.

Điều tương tự cũng xảy ra với phần mềm máy tính để bàn. Khi tôi muốn tắt trình duyệt của mình, thường phải mất AGES để tắt. Không có gì trình duyệt của tôi cần làm mà phải mất nhiều hơn một vài giây. Khi tôi yêu cầu nó tắt nó nên quản lý để làm điều đó ngay lập tức. Khi nó không, tốt, sau đó chúng tôi rút kill -9 và tạo ra nó.


4
Tôi đồng ý rằng một quy trình nên được viết để khoan dung với một thất bại như vậy, nhưng tôi nghĩ rằng vẫn còn thực tế xấu để làm điều này. Một cơ sở dữ liệu sẽ phục hồi nhưng nó có thể phát hiện việc hủy bỏ thô lỗ và sau đó kích hoạt kiểm tra phục hồi đáng kể khi được khởi động lại. Và những gì về các yêu cầu một quá trình đang phục vụ? Tất cả họ sẽ bị cắt đứt ngay lập tức, khách hàng có thể có lỗi và thất bại quá?
Daniel James Bryars

3
Cơ sở dữ liệu không thể bị giết bất cứ lúc nào không phải là cơ sở dữ liệu đáng tin cậy. Đây là một yêu cầu khá cơ bản nếu bạn yêu cầu sự nhất quán. Đối với khách hàng: nếu họ đi dữ liệu haywire và hỏng khi kết nối bị đứt, họ cũng được thiết kế xấu. Cách để giải quyết mất dịch vụ là thông qua các chiến lược dự phòng / thử lại tự động. Thông thường đối với hầu hết các hệ thống bị lỗi nhanh, tốt hơn là cố gắng phục hồi.
borud

4
@borud Nó có thể không phải là phần mềm được viết hoàn hảo, nhưng đó là phần mềm mọi người sử dụng mọi lúc. Quản trị viên hệ thống nào có thể thoải mái khi luôn có thể chọn phần mềm được viết hoàn hảo, để luôn phục hồi một cách duyên dáng sau sự gián đoạn đột ngột? Không nhiều. Cá nhân tôi sử dụng các kịch bản tắt máy, và bắt đầu / dừng các quá trình thông qua điều này. Nếu họ không phản hồi kịch bản tắt máy (báo hiệu đúng quy trình), tôi sẽ giết -9.
Steve Sether

2
Không có sự khác biệt giữa nấu các món cơ bản và các món ăn phức tạp hơn đối với các công cụ. Sự khác biệt là đầu bếp. (Tuy nhiên, nếu bạn dành nhiều thời gian nấu nướng như tôi, bạn sẽ nhận ra rằng sự mạnh mẽ là yêu cầu tối thiểu trong dụng cụ nhà bếp và hầu hết những người bán đồ dùng nhà bếp cho người tiêu dùng sẽ không biết một công cụ tồi từ một công cụ tuyệt vời.)
borud

1
Vậy bạn có khuyến khích mọi người cẩu thả vì khó làm việc đúng không? Ngày càng có nhiều phần mềm được chạy trong môi trường hoạt động là phù du. Nếu bạn viết phần mềm trở nên khó xử nếu nó không được tắt chính xác, bạn sẽ gặp khó khăn trong việc thuyết phục nhà tuyển dụng thuê bạn làm nhà phát triển.
borud

10

Không được đề cập trong tất cả các câu trả lời khác là một trường hợp kill -9hoàn toàn không hoạt động, khi một quá trình đang <defunct>và không thể bị giết:

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

Điều gì không còn tồn tại cho một quá trình và tại sao nó không bị giết?

Vì vậy, trước khi bạn cố gắng chạy kill -9một <defunct>quy trình ps -efđể xem cha mẹ của anh ta là gì và thử -15(TATE) hoặc -2(INT) và cuối cùng -9(KILL) trên cha mẹ anh ta.

Lưu ý: những gì ps -efkhông .

Chỉnh sửa và thận trọng sau này: Hãy thận trọng khi giết các quá trình, cha mẹ hoặc con cái của họ, vì chúng có thể để các tệp được mở hoặc bị hỏng, các kết nối chưa hoàn thành, có thể làm hỏng cơ sở dữ liệu, trừ khi bạn biết những gì kill -9cho một quy trình, chỉ sử dụng nó như là phương sách cuối cùng và nếu bạn cần chạy kill, hãy sử dụng các tín hiệu được chỉ định ở trên trước khi sử dụng-9 (KILL)


6

Không bao giờ không bao giờ làm a kill -9 1. Ngoài ra, tránh giết trên các quy trình nhất định như mount`. Khi tôi phải giết rất nhiều tiến trình (ví dụ như phiên X bị treo và tôi phải giết tất cả các quy trình của một người dùng nhất định), tôi đảo ngược thứ tự của các quy trình. Ví dụ:

ps -ef|remove all processes not matching a certain criteria| awk '{print $2}'|ruby -e '$A=stdin.readlines; A.reverse.each{|a| puts "kill -9 #{a}"}'|bash

Hãy nhớ rằng killkhông dừng lại một quá trình và giải phóng tài nguyên của nó. Tất cả những gì nó làm là gửi tín hiệu SIGKILL cho quá trình; bạn có thể kết thúc với một quá trình treo.


1
Các downvote là một người khác. Nhưng tài nguyên nào không được phát hành? Bạn chỉ có nghĩa là quá trình không thể thực hiện dọn dẹp bình thường của nó? Điều gì về khóa tập tin, semaphores, vv? Bạn có thể xây dựng?
Mikel

Có vẻ như bộ nhớ chia sẻ SysV và semaphores sẽ phải được dọn sạch, ít nhất. archives.postgresql.org/pgsql-general/2006-10/msg01065.php
Mikel

8
Câu trả lời này là một phần khó hiểu và một phần sai. kill -9 1chỉ bị bỏ qua dưới hầu hết các đơn vị. Không cần để tránh kill -9cho mount, nhưng không có điểm trong đó một trong hai. Tôi không biết ý của bạn là gì khi đảo ngược thứ tự của các quy trình. kill -9không dừng lại (như trong, giết) một quy trình, mà không cho nó cơ hội khiếu nại, tuy nhiên việc giết chóc sẽ không xảy ra ngay lập tức nếu quy trình đó nằm trong một cuộc gọi hệ thống không bị gián đoạn . Giết một quá trình kill -9không giải phóng hầu hết các tài nguyên, nhưng không phải tất cả .
Gilles

5

Giết quá trình willy-nilly không phải là một động thái suôn sẻ: dữ liệu có thể bị mất, các ứng dụng được thiết kế kém có thể tự phá vỡ theo những cách tinh tế không thể sửa được nếu không cài đặt lại .. nhưng nó hoàn toàn phụ thuộc vào việc biết cái gì và cái gì không an toàn trong tình hình đưa ra. và những gì sẽ có nguy cơ. Người dùng nên biết một quy trình là gì, hoặc nên làm gì và các ràng buộc của nó là gì (đĩa IOPS, rss / hoán đổi) và có thể ước tính thời gian của một quá trình chạy dài (giả sử sao chép tệp, mã hóa lại mp3, di chuyển email, sao lưu, [thời gian yêu thích của bạn ở đây].)

Hơn nữa, gửi SIGKILLđến một pid không đảm bảo sẽ giết nó. Nếu nó bị kẹt trong một tòa nhà cao tầng hoặc đã được khoanh vùng ( Ztrong ps), nó có thể tiếp tục được khoanh vùng. Đây thường là trường hợp của ^ Z một quá trình chạy dài và quên bgtrước khi thử kill -9nó. Một đơn giản fgsẽ kết nối lại stdin / stdout và có thể bỏ chặn quá trình, thường sau đó là quá trình kết thúc. Nếu nó bị kẹt ở nơi khác hoặc trong một số dạng bế tắc hạt nhân khác, chỉ có thể khởi động lại có thể loại bỏ quá trình. (Các quy trình Zombie đã chết sau khi SIGKILLđược xử lý bởi kernel (không có mã vùng người dùng nào nữa sẽ chạy), thường có một lý do kernel (tương tự như bị "chặn" chờ trên một tòa nhà để kết thúc) cho quá trình không kết thúc.)

Ngoài ra, nếu bạn muốn giết một tiến trình và tất cả các con của nó, hãy tập thói quen gọi killvới PID bị phủ định, không chỉ riêng cho PID . Không có gì đảm bảo SIGHUP, SIGPIPEhoặc SIGINTcác tín hiệu khác được dọn sạch sau nó, và có một loạt các quy trình bị từ chối để dọn dẹp (hãy nhớ mongrel?) Thật khó chịu.

Phần thưởng độc ác: kill -9 -1gây hại nhiều hơn một chút so với kill -9 1(Đừng làm gốc trừ khi bạn muốn xem điều gì xảy ra trên máy ảo không quan trọng, vứt bỏ)


3

Tại sao bạn không muốn kill -9một quá trình bình thường

Theo man 7 signal:

Các tín hiệu SIGKILL và SIGSTOP không thể bị bắt, chặn hoặc bỏ qua.

Điều này có nghĩa là ứng dụng nhận được một trong hai tín hiệu này không thể "bắt" chúng thực hiện bất kỳ hành vi tắt máy nào.

Bạn nên làm gì trước khi chạy kill -9trên một quy trình

Bạn nên đảm bảo rằng trước khi gửi tín hiệu đến quy trình mà bạn:

  1. Đảm bảo rằng quy trình không bận rộn (tức là thực hiện "công việc"); gửi một kill -9quá trình về cơ bản sẽ dẫn đến việc mất dữ liệu này.
  2. Nếu quy trình là một cơ sở dữ liệu không đáp ứng, hãy đảm bảo rằng nó đã xóa bộ nhớ cache trước. Một số cơ sở dữ liệu hỗ trợ gửi các tín hiệu khác đến quy trình để buộc xóa bộ đệm của nó.

3

Tôi đã tạo một tập lệnh giúp tự động hóa vấn đề này.

Nó dựa trên câu trả lời hoàn chỉnh 2 của tôi trong một câu hỏi rất giống nhau ở stackoverflow .

Bạn có thể đọc tất cả các giải thích ở đó. Để tóm tắt, tôi muốn giới thiệu chỉ SIGTERMSIGKILL, hoặc thậm chí SIGTERM, SIGINTSIGKILL. Tuy nhiên tôi đưa ra nhiều lựa chọn hơn trong câu trả lời đầy đủ.

Xin vui lòng, tải về (sao chép) nó từ kho github để giết chết 1

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.