Câu trả lời:
kill -9
( SIGKILL ) luôn hoạt động, miễn là bạn có quyền giết quá trình. Về cơ bản, quá trình phải được bắt đầu bởi bạn và không được setuid hoặc setgid, hoặc bạn phải root. Có một ngoại lệ: ngay cả root cũng không thể gửi tín hiệu gây tử vong cho PID 1 ( init
quá trình).
Tuy nhiên kill -9
không được đảm bảo để làm việc ngay lập tức . Tất cả các tín hiệu, bao gồm SIGKILL, được phân phối không đồng bộ: hạt nhân có thể mất thời gian để phân phối chúng. Thông thường, việc cung cấp tín hiệu mất tối đa vài micro giây, chỉ cần thời gian để mục tiêu có được một lát cắt thời gian. Tuy nhiên, nếu mục tiêu đã chặn tín hiệu , tín hiệu sẽ được xếp hàng cho đến khi mục tiêu mở khóa.
Thông thường, các quy trình không thể chặn SIGKILL. Nhưng mã kernel có thể và các tiến trình thực thi mã kernel khi chúng gọi các cuộc gọi hệ thống . Mã hạt nhân chặn tất cả các tín hiệu khi làm gián đoạn cuộc gọi hệ thống sẽ dẫn đến cấu trúc dữ liệu được hình thành xấu ở đâu đó trong kernel hoặc nói chung là trong một số bất biến kernel bị vi phạm. Vì vậy, nếu (do lỗi hoặc xác định sai) một khối gọi hệ thống vô thời hạn, có thể không có cách nào để giết quá trình. (Nhưng quá trình sẽ bị hủy nếu nó hoàn thành lệnh gọi hệ thống.)
Một quá trình bị chặn trong một cuộc gọi hệ thống là trong giấc ngủ không bị gián đoạn . Lệnh ps
hoặc top
sẽ (trên hầu hết các thông báo) hiển thị nó ở trạng thái D
(ban đầu là cho d d isk, tôi nghĩ vậy).
Một trường hợp cổ điển của giấc ngủ dài không thể gián đoạn là các quá trình truy cập các tệp qua NFS khi máy chủ không phản hồi; triển khai hiện đại có xu hướng không áp đặt giấc ngủ không bị gián đoạn (ví dụ: trong Linux, intr
tùy chọn gắn kết cho phép tín hiệu làm gián đoạn truy cập tệp NFS).
Đôi khi bạn có thể thấy các mục được đánh dấu Z
(hoặc H
trong Linux, tôi không biết phân biệt là gì) trong ps
hoặc top
đầu ra. Đây là những quy trình không phải là quy trình, chúng là các quy trình zombie, không có gì khác hơn là một mục trong bảng quy trình, được giữ xung quanh để quy trình cha mẹ có thể được thông báo về cái chết của con của nó. Họ sẽ biến mất khi quá trình cha mẹ chú ý (hoặc chết).
man 5 nfs
: " Tùy chọn intr
/ nointr
mount không được dùng sau kernel 2.6.25. Chỉ SIGKILL mới có thể làm gián đoạn hoạt động NFS đang chờ xử lý trên các kernel này và nếu được chỉ định, tùy chọn mount này sẽ bị bỏ qua để cung cấp khả năng tương thích ngược với các kernel cũ hơn."
sshfs
tiến trình (và tương tự với bất kỳ hệ thống tệp FUSE nào khác: bạn luôn có thể buộc ngắt kết nối theo cách này).
Đôi khi quá trình tồn tại và không thể bị giết do:
top
đó có tín hiệu Ztop
đó có tín hiệu của D.Có vẻ như bạn có thể có một quá trình zombie . Điều này là vô hại: tài nguyên duy nhất mà quá trình zombie tiêu thụ là một mục trong bảng quy trình. Nó sẽ biến mất khi quá trình cha mẹ chết hoặc phản ứng với cái chết của con nó.
Bạn có thể xem liệu quá trình là một zombie bằng cách sử dụng top
hoặc lệnh sau:
ps aux | awk '$8=="Z" {print $2}'
ps
. Ai có thể chắc chắn rằng trường bắt buộc sẽ luôn là số 8, với tất cả các triển khai ps
trong tất cả các Thông báo?
Kiểm tra của bạn /var/log/kern.log
và /var/log/dmesg
(hoặc tương đương) cho bất kỳ manh mối. Theo kinh nghiệm của tôi, điều này chỉ xảy ra với tôi khi kết nối mạng của NFS đột ngột bị rớt hoặc trình điều khiển thiết bị bị hỏng. Tôi có thể xảy ra nếu một ổ cứng bị hỏng.
Bạn có thể sử dụng lsof
để xem các tập tin thiết bị mà quá trình đã mở.
kill -9
thường không hoạt động, thậm chí sau khi chờ 60 phút. Giải pháp duy nhất là khởi động lại.
Nếu câu trả lời của @ Maciej và @ Gilles không giải quyết được vấn đề của bạn và bạn không nhận ra quy trình (và hỏi nó là gì với bản phân phối của bạn thì không có câu trả lời). Kiểm tra Rootkit và bất kỳ dấu hiệu nào khác mà bạn đã sở hữu . Một rootkit có nhiều khả năng ngăn bạn giết quá trình. Trong thực tế, nhiều người có khả năng ngăn bạn nhìn thấy chúng. Nhưng nếu họ quên sửa đổi 1 chương trình nhỏ, họ có thể bị phát hiện (ví dụ họ đã sửa đổi top
, nhưng không sửa đổi htop
). Nhiều khả năng đây không phải là trường hợp nhưng an toàn tốt hơn là xin lỗi.
Kill thực sự có nghĩa là gửi tín hiệu. có nhiều tín hiệu bạn có thể gửi. giết -9 là một tín hiệu đặc biệt.
Khi gửi tín hiệu ứng dụng xử lý nó. nếu không phải là hạt nhân đối phó với nó. để bạn có thể bẫy tín hiệu trong ứng dụng của bạn.
Nhưng tôi đã nói kill -9 thật đặc biệt. Điều đặc biệt là ứng dụng không nhận được nó. nó đi thẳng vào kernel mà sau đó thực sự giết chết ứng dụng ở cơ hội đầu tiên có thể. nói cách khác giết chết nó
kill -15 gửi tín hiệu SIGTERM, viết tắt của TÍN HIỆU TÍN HIỆU nói cách khác nói cho ứng dụng thoát. Đây là cách thân thiện để nói với một ứng dụng đã đến lúc tắt máy. nhưng nếu ứng dụng không phản hồi kill -9 sẽ giết nó.
nếu kill -9 không hoạt động thì có lẽ điều đó có nghĩa là kernel của bạn đã hết. khởi động lại theo thứ tự. Tôi không thể nhớ điều đó đã từng xảy ra.
Đầu tiên, hãy kiểm tra xem đó có phải là quá trình Zombie không (rất có thể):
ps -Al
Bạn sẽ thấy một cái gì đó như:
0 Z 1000 24589 1 0 80 0 - 0 exit ? 00:00:00 soffice.bin <defunct>
(Lưu ý "Z" bên trái)
Nếu cột thứ 5 không phải là 1, thì có nghĩa là nó có một quá trình cha. Hãy thử giết id quá trình cha mẹ .
Nếu PPID của nó = 1, ĐỪNG GIẾT NÓ !! , nghĩ rằng những thiết bị hoặc quy trình khác có thể liên quan đến nó.
Ví dụ: nếu bạn đang sử dụng thiết bị được gắn hoặc samba, hãy thử ngắt kết nối thiết bị. Điều đó có thể giải phóng quá trình Zombie.
LƯU Ý : Nếu ps -Al
(hoặc top
) hiển thị "D" thay vì "Z", nó có thể liên quan đến ngàm từ xa (như NFS). Theo kinh nghiệm của tôi, khởi động lại là cách duy nhất để đi đến đó, nhưng bạn có thể kiểm tra các câu trả lời khác bao gồm trường hợp đó chi tiết hơn.
Như những người khác đã đề cập, một quá trình trong giấc ngủ không bị gián đoạn có thể bị giết ngay lập tức (hoặc, trong một số trường hợp, tất cả). Đáng lưu ý rằng một trạng thái quy trình khác, TASK_KILLABLE, đã được thêm vào để giải quyết vấn đề này trong một số trường hợp nhất định, đặc biệt là trường hợp phổ biến trong đó quy trình đang chờ trên NFS. Xem http://lwn.net/Articles/288056/
Thật không may, tôi không tin rằng nó được sử dụng ở bất cứ đâu trong kernel trừ NFS.
ls
quá trình truy cập vào một sshfs
mount, khi máy chủ từ xa không thể truy cập được. Có giải pháp nào cho FUSE hoặc sshfs, mà tôi có thể sử dụng trong tương lai để tránh những tình huống như vậy không? 2.6.30 kernel
Làm một kịch bản nhỏ giúp tôi rất nhiều hãy xem!
Bạn có thể sử dụng nó để giết bất kỳ tiến trình nào có tên đã cho trong đường dẫn của nó (chú ý đến điều này !!) Hoặc bạn có thể giết bất kỳ quy trình nào của người dùng đã cho bằng cách sử dụng tham số "-u username".
#!/bin/bash
if [ "$1" == "-u" ] ; then\n
PID=`grep "$2" /etc/passwd | cut -d ":" -f3`
processes=`ps aux | grep "$PID" | egrep -v "PID|ps \-au|killbyname|grep" | awk '{ print $2}'`
echo "############# Killing all processes of user: $2 ############################"
else
echo "############# Killing processes by name: $1 ############################"
processes=`ps aux | grep "$1" | egrep -v "killbyname|grep" | awk '{ print $2}' `
fi
for process in $processes ; do
# "command" stores the entire commandline of the process that will be killed
#it may be useful to show it but in some cases it is counter-productive
#command=`ps aux | grep $process | egrep -v "grep" | awk '{ print $2 }'`
echo "Killing process: $process"
echo ""
kill -9 $process
done
Có những trường hợp ngay cả khi bạn gửi kill -9 đến một tiến trình, pid đó sẽ dừng lại, nhưng quá trình sẽ tự động khởi động lại (ví dụ, nếu bạn thử với gnome-panel
nó, nó sẽ khởi động lại): đó có thể là trường hợp ở đây không?
từ đây ban đầu :
kiểm tra nếu strace cho thấy bất cứ điều gì
strace -p <PID>
thử gắn vào quy trình với gdb
gdb <path to binary> <PID>
nếu quá trình tương tác với một thiết bị mà bạn có thể ngắt kết nối, hãy tháo mô-đun hạt nhân hoặc ngắt kết nối / rút phích cắm vật lý ... thì hãy thử điều đó.
Tôi đã có loại vấn đề này. Đây là một chương trình mà tôi đã khởi chạy strace
và bị gián đoạn với Ctrl
+ C
. Nó đã kết thúc ở T
trạng thái (truy tìm hoặc dừng lại). Tôi không biết chính xác nó đã xảy ra như thế nào, nhưng nó không thể giết được SIGKILL
.
Tóm lại, tôi đã giết nó với gdb
:
gdb -p <PID>
> kill
Kill the program being debugged? (y or n) y
> quit
Dựa trên manh mối từ câu trả lời của gilles, tôi đã có một quá trình được đánh dấu "Z" ở đầu (tính <defunct>
bằng ps) đang sử dụng tài nguyên hệ thống, nó thậm chí còn có một cổng mở là LISTEN'ing và bạn có thể kết nối với cổng đó. Điều này là sau khi thực hiện một kill -9
trên nó. Cha mẹ của nó là "1" (tức là init
) vì vậy về mặt lý thuyết, nó chỉ nên được lặp lại và biến mất. Nhưng không phải, nó vẫn lảng vảng xung quanh, mặc dù không chạy và "không chết"
Vì vậy, trong trường hợp của tôi, đó là zombie nhưng vẫn tiêu tốn tài nguyên ... FWIW.
Và nó đã không thể đánh bằng bất kỳ số lượng kill -9
's
Và cha mẹ của nó là init
nhưng nó đã không được gặt hái (làm sạch). Tức là init
đã có một đứa trẻ zombie.
Và khởi động lại là không cần thiết để khắc phục vấn đề. Mặc dù khởi động lại "sẽ có tác dụng" xung quanh vấn đề / làm cho nó tắt nhanh hơn. Chỉ cần không duyên dáng, mà vẫn có thể.
Và đó là một cổng LISTEN được sở hữu bởi một quá trình zombie (và một vài cổng khác giống như trạng thái CLOSE_WAIT được kết nối localhost với localhost). Và nó thậm chí vẫn chấp nhận kết nối. Ngay cả như một thây ma. Tôi đoán nó đã không được dọn dẹp các cổng nhưng các kết nối đến vẫn được thêm vào hồ sơ tồn đọng của cổng nghe tcp, mặc dù chúng không có cơ hội được chấp nhận.
Nhiều trong số trên được tuyên bố là "không thể" trên các địa điểm khác nhau trong các interwebs.
Hóa ra tôi có một luồng nội bộ trong đó đang thực hiện một "cuộc gọi hệ thống" (trong trường hợp này là ioctl), phải mất vài giờ để quay lại (đây là hành vi dự kiến). Rõ ràng hệ thống không thể giết quá trình "mọi cách" cho đến khi nó trở về từ ioctl
cuộc gọi, đoán nó đi vào vùng đất hạt nhân. Sau một vài giờ nó trở lại, mọi thứ đã được dọn sạch và tất cả các ổ cắm đều tự động đóng lại, vv như mong đợi. Đó là một thời gian mòn mỏi trên tử tù! Hạt nhân đã kiên nhẫn chờ đợi để giết nó.
Vì vậy, để trả lời OP, đôi khi bạn phải chờ đợi. Một thời gian dài. Sau đó, giết cuối cùng sẽ mất.
Đồng thời kiểm tra dmesg để xem có hoảng loạn kernel không (tức là lỗi kernel).