Tất nhiên cách thô thiển nhất là gõ ps auxww | grep PID để tìm, nhưng bài viết này không viết về cái thô thiển ấy.
Trên Linux, có sử dụng một thứ gọi là proc filesystem. Với mỗi process đang chạy có pid là PID, sẽ tồn tại tương ứng một thư mục /proc/PID
Vậy trên các OS sử dụng Linux, có thể kiểm tra thư mục này có tồn tại không là sẽ biết process có đang chạy hay không.
# ps -ef | grep bin[d]Có vẻ đã bớt thô thiển hơn nhiều, nhưng cách này chỉ áp dụng được với các hệ điều hành dùng Linux (và một số hệ điều hành hỗ trợ procfs thanks +Le Manh Cuong) . Vậy còn cách nào hơn? có thể chạy trên OS X, BSD ...?
bind 32511 1 0 05:33 ? 00:00:00 /usr/sbin/named -u bind
# python -c 'import os; print os.path.isdir("/proc/32511")'
True
# process với PID 32519 không tồn tại
# python -c 'import os; print os.path.isdir("/proc/32519")' && ps -ef | grep [3]2519
False
Kill it!
# whatis killMặc dù tên chương trình là ``kill`` nhưng bản chất là nó gửi một signal (tín hiệu) đến một process.
kill (1) - send a signal to a process
kill (2) - send signal to a process
Chú ý, để có man 2 kill, cần phải cài gói ``manpages-dev``.
Trong man 2 kill có viết: kill() system call gửi signal ``sig`` đến ``pid`` (một hoặc một nhóm process). Giá trị của sig là các giá trị mô tả trong man 2 sigaction hoặc có thể là ``0``, khi gửi đi sig = 0, cơ chế kiểm tra lỗi vẫn được thực hiện nhưng không có signal nào được gửi đi thực sự.
Tức nếu PID đó không tồn tại, sẽ báo lỗi, còn nếu nó tồn tại thì không có gì xảy ra.
Sysadmin version:
# kill -s 0 32511 # không có gì xảy ra, process đang chạy
# kill -s 0 32519
-bash: kill: (32519) - No such process # báo lỗi, process không tồn tại.
Python 2.7 CLI:
# python -c 'import os; os.kill(32511, 0)' # không có gì xảy raVậy để kiểm tra một process có PID nào đó có đang chạy không, có thể sử dụng system call ``kill`` gửi đi signal 0 và xử lý kết quả trả về.
# python -c 'import os; os.kill(32519, 0)'
Traceback (most recent call last):
File "<string>", line 1, in <module>
OSError: [Errno 3] No such process
Happy killing!
by hvn@familug.org
ở một nơi xa xôi không ai biết tới
"nhưng cách này chỉ áp dụng được với các hệ điều hành dùng Linux." ==> Điều này không đúng. Có khá nhiều HĐH ngoài Linux có sử dụng procfs, ví dụ: AIX, Solaris, Plan 9, NetBSD có thể giả lập `/proc` như linux.
ReplyDeleteMột điều cần lưu ý nữa là khi `kill -s 0` thành công chỉ đảm bảo là process với PID và đủ permission đang chạy, điều này không đảm bảo đó là process mà bạn mong muốn. Ví dụ chạy vài câu lệnh sleep, kill -s 0 -- $(pgrep sleep) có thể fail một trong các sleep process "died" trong khi pgrep và kill đang chạy.
> ví dụ: AIX, Solaris, Plan 9, NetBSD có thể giả lập `/proc` như linux.
ReplyDeletecám ơn bạn, mình đã update bài viết.
> điều này không đảm bảo đó là process mà bạn mong muốn
mình không hiểu rõ chỗ này lắm, ý bạn là việc một process cũ die và 1 process mới có thể dùng PID của process cũ đã die?
Đúng rồi bạn. Mình chỉ muốn nhấn mạnh 1 điểm là việc monitor 1 process mà dựa vào PID của nó thì có thể không chính xác.
ReplyDeleteCách tốt nhất là dựa vào Parent của thằng process.
như mình biết thì các tool monitor 1 process (nrpe/diamond) đều sử dụng tên process (name/exe/cmdline). Bài viết này chủ yếu nhằm tới một process có PID xác định có đang chạy không (mình sẽ update vào bài viết).
DeleteCòn dựa vào parent thì có vẻ không hợp lý (rất nhiều process cùng có parent PID = 1)
Parent cũng manage process bằng PID mà bạn :D
DeleteBài này chỉ là dùng tool để kiểm tra nên việc kiểm tra sẽ không thể chính xác như là parent quản lý các tiến trình con được.
@Hưng Việt Nguyễn: Tại sao lại không hợp lý? Việc rất nhiều process cùng có parent PID = 1 không liên quan đến việc monitor này.
ReplyDeleteMột process PID sẽ không được sử dụng lại cho đến khi parent của nó công nhận là nó die (Đó là lý do tại sao có zombie process, khi mà parent process không thế xác nhận là PID die).
bạn có thể đưa ra 1 ví dụ (script?) để thực hiện việc manage một process sử dụng PPID của nó không? như trong ví dụ chạy vài câu lệnh sleep và dùng kill -0 ...
DeleteHình như bạn có chút hiểu lầm ở đây. Mình nói là dựa vào parent chứ không phải sử dụng PPID.
ReplyDeleteVí dụ điển hình là trong bash, khi bạn thực hiện 1 lệnh ở background (cmd &) sau đó dùng builtin wait, thì lúc này bash script chỉ quit khi command thực hiện xong. Tức là bạn đã giao việc manage process chạy cmd cho parent của nó, là bash.
Nếu không dùng wait thì bash quit ngay, trong khi cmd vẫn đang chạy và chuyển PPID sang 1.
$ cat > test.sh
#!/bin/bash
echo start
sleep 60 &
echo end
đúng là có hiểu lầm ở đây, vì bày này mình viết nhằm tới việc kiểm tra một PID có đang chạy không từ bên ngoài (vd nrpe script) chứ không định monitor nó theo nghĩa manage process từ phía parent với subprocess.
DeleteCám ơn bạn đã dành thời gian để thảo luận về bài viết, rất mong bạn tiếp tục đưa ra những thảo luận bổ ích trong các bài sau.