Thursday, 26 March 2015

Kiểm tra một process đang chạy hay không (dựa vào PID)?

NOTICE: bài viết tập trung vào vấn đề "kiểm tra xem một process có đang chạy hay không dựa vào PID đã biết"

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]
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
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 ...?

Kill it!

# whatis kill
kill (1)             - send a signal to a process
kill (2)             - send signal to a process
Mặ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.
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 ra
# 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
Vậ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ề.
Happy killing!

by hvn@familug.org
ở một nơi xa xôi không ai biết tới