Quản lý tiến trình trong Unix/Linux

Khi bạn chạy một chương trình trên hệ thống Unix, hệ thống tạo một môi trường đặc biệt cho chương trình đó. Môi trường này chứa mọi thứ cần thiết cho hệ thống chạy chương trình nếu như không có chương trình khác đang chạy trên hệ thống.

Bất cứ khi nào bạn thông báo một lệnh trong Unix, nó tạo hoặc bắt đầu một tiến trình mới. Khi bạn cố gắng thực hiện một lệnh ls để liệt kê nội dung thư mục, bạn bắt đầu một tiến trình. Một tiến trình, hiểu theo cách đơn giản, là một ví dụ của một chương trình đang chạy.

Hệ điều hành theo dõi các tiến trình thông qua một ID có 5 chữ số mà được biết như là ID pid hoặc Process ID. Mỗi tiến trình trong hệ thống có một pid duy nhất.

Pid thường lặp lại bởi vì tất cả các số có thể đã được sử dụng và pid kế tiếp lặp lại. Tại bất kỳ lúc nào, không thể có hai tiến trình với hai pid giống nhau cùng tồn tại trong hệ thống bởi vì nó là pid mà Unix sử dụng để theo dõi mỗi tiến trình.

Bắt đầu một tiến trình trong Unix/Linux

Khi bạn bắt đầu một tiến trình (chạy một lệnh), có 2 cách để bạn chạy nó:

  • Foreground Process
  • Background Process

Tiến trình Foreground trong Unix/Linux

Theo mặc định, mọi tiến trình mà bạn bắt đầu chạy là Foreground Process. Nó nhận input từ bàn phím và gửi output tới màn hình.

Bạn có thể quan sát điều này xảy ra với lệnh ls. Nếu bạn muốn liệt kê tất cả các file trong thư mục hiện tại, bạn có thể sử dụng lệnh sau:

$ls ch*.doc

Nó sẽ hiển thị tất cả file mà tên bắt đầu với ch và kết thúc với .doc.

ch01-1.doc   ch010.doc  ch02.doc    ch03-2.doc 
ch04-1.doc   ch040.doc  ch05.doc    ch06-2.doc
ch01-2.doc   ch02-1.doc

Tiến trình chạy trong Foreground, kết quả của nó được hướng trực tiếp trên màn hình của tôi và nếu lệnh ls muốn bất kỳ đầu vào nào, nó đợi từ bàn phím.

Trong khi một chương trình đang chạy trong Foreground và cần một khoảng thời gian dài, chúng ta không thể chạy bất kỳ lệnh khác (bắt đầu một tiến trình khác) bởi vì dòng nhắc không có sẵn tới khi chương trình đang chạy kết thúc tiến trình và thoát ra.

Tiến trình Background trong Unix/Linux

Background Process chạy mà không được kết nối với bàn phím của bạn. Nếu tiến trình Background yêu cầu bất cứ đầu vào từ bàn phím, nó đợi.

Lợi thế của chạy một chương trình trong Background là bạn có thể chạy các lệnh khác; bạn không phải đợi tới khi nó kết thúc để bắt đầu một tiến trình mới!

Cách đơn giản nhất để bắt đầu một tiến trình Background là thêm dấu và (&) tại phần cuối của lệnh.

$ls ch*.doc &

Điều này cũng hiển thị tất cả các file mà tên bắt đầu với ch và kết thúc với .doc:

ch01-1.doc   ch010.doc  ch02.doc    ch03-2.doc 
ch04-1.doc   ch040.doc  ch05.doc    ch06-2.doc
ch01-2.doc   ch02-1.doc

Tại đây, nếu lệnh ls muốn bất kỳ đầu vào nào (mà nó không), nó tiến vào trạng thái dừng tới khi bạn di chuyển nó vào trong Foreground và cung cấp cho nó dữ liệu từ bàn phím.

Dòng đầu tiên chứa các thông tin về Background Process - số công việc (job number) và Process ID. Bạn cần biết về Job number để thao tác nó giữa Background và Foreground.

Nếu bạn nhấn phím Enter bây giờ, bạn nhìn thấy như sau:

[1]   +   Done                 ls ch*.doc &
$

Dòng đầu tiên nói cho bạn rằng lệnh ls trong Background Process đã hoàn thành một cách thành công. Dòng thứ hai là một dòng nhắc cho một lệnh khác.

Liệt kê các tiến trình đang chạy trong Unix/Linux

Nó là dễ dàng để quan sát các tiến trình của bạn bằng cách chạy lệnh ps (viết tắt của process status) như sau:

$ps
PID       TTY      TIME        CMD
18358     ttyp3    00:00:00    sh
18361     ttyp3    00:01:31    abiword
18789     ttyp3    00:00:00    ps

Một trong những flag được sử dụng cho ps là -f (viết tắt của full), mà cung cấp nhiều thông tin như ví dụ dưới đây:

$ps -f
UID      PID  PPID C STIME    TTY   TIME CMD
amrood   6738 3662 0 10:23:03 pts/6 0:00 first_one
amrood   6739 3662 0 10:22:54 pts/6 0:00 second_one
amrood   3662 3657 0 08:10:53 pts/6 0:00 -ksh
amrood   6892 3662 4 10:51:50 pts/6 0:00 ps -f

Dưới đây là sự miêu tả của tất cả các file được hiển thị bởi lệnh ps -f.

Cột
Miêu tả
UID
ID người sử dụng mà tiến trình này thuộc sở hữu (người chạy nó).
PID
Process ID.
PPID
Process ID gốc (ID của tiến trình mà bắt đầu nó).
C
CPU sử dụng của tiến trình.
STIME
Thời gian bắt đầu tiến trình.
TTY
Kiểu terminal liên kết với tiến trình.
TIME
Thời gian CPU bị sử dụng bởi tiến trình.
CMD
Lệnh mà bắt đầu tiến trình này.

Dừng tiến trình trong Unix/Linux

Kết thúc một tiến trình có thể được thực hiện theo vài cách khác nhau. Thông thường, từ một lệnh console-based, gửi CTRL + C bằng gõ phím (mặc định là ký tự ngắt) sẽ hủy lệnh. Nó làm việc khi tiến trình đang chạy trong chế độ Foreground.

Nếu một tiến trình đang chạy trong chế độ Background, thì đầu tiên bạn cần nhận ID công việc (job ID) bằng cách sử dụng lệnh ps và sau đó bạn có thể sử dụng lệnh kill để khử tiến trình như sau:

$ps -f
UID      PID  PPID C STIME    TTY   TIME CMD
amrood   6738 3662 0 10:23:03 pts/6 0:00 first_one
amrood   6739 3662 0 10:22:54 pts/6 0:00 second_one
amrood   3662 3657 0 08:10:53 pts/6 0:00 -ksh
amrood   6892 3662 4 10:51:50 pts/6 0:00 ps -f
$kill 6738
Terminated

Ở đây lệnh kill sẽ kết thúc tiến trình first_one. Nếu một tiến trình thường bỏ qua một lệnh kill, bạn có thể sử dụng kill -9 theo sau bởi Process ID như sau:

$kill -9 6738
Terminated

Tiến trình mẹ và tiến trình con trong Unix/Linux

Mỗi một tiến trình Unix có hai ID được gán cho nó: Process ID (pid) và Parent Process ID (ppid). Mỗi tiến trình trong hệ thống có một Parent Process (gốc).

Hầu hết các lệnh mà bạn chạy có Shell như là mẹ của nó. Kiểm tra ví dụ ps -f mà tại đây lệnh này liệt kê cả Process ID và Process ID gốc.

Tiến trình Zombie và Orphan

Thông thường, khi một tiến trình con bị khử, Parent Process được thông báo thông qua ký hiệu SIGCHLD. Sau đó, tiến trình gốc có thể thực hiện một vài công việc khác hoặc bắt đầu lại tiến trình con nếu cần thiết. Tuy nhiên, đôi khi Parent Process bị khử trước khi tiến trình con của nó bị khử. Trong trường hợp này, Parent Process của tất cả các tiến trình, "tiến trình init", trở thành PPID mới (Process ID mẹ). Đôi khi những tiến trình này được gọi là tiến trình Orphan.

Khi một tiến trình bị khử, danh sách liệt kê ps có thể vẫn chỉ tiến trình với trạng thái Z. Đây là trạng thái Zombie, hoặc tiến trình không tồn tại. Tiến trình này bị khử và không được sử dụng. Những tiến trình này khác với tiến trình orphan. Nó là những tiến trình mà đã chạy hoàn thành nhưng vần có một cổng vào trong bảng tiến trình.

Tiến trình Daemon trong Unix/Linux

Daemon là các Background Process liên quan tới hệ thống mà thường chạy với quyền hạn truy cập của root và các dịch vụ yêu cầu từ tiến trình khác.

Một tiến trình deamon không có terminal điều khiển. Nó không thể mở /dev/tty. Nếu bạn thực hiện một ps-ef và quan sát vào trường tty, tất cả deamon sẽ có một dấu ? cho tty.

Để rõ hơn, một deamon chỉ là một tiến trình mà chạy trong Background, thường đợi cho cái gì đó xảy ra mà nó có khả năng làm việc với, giống như máy in deamon đang đợi các lệnh in.

Nếu bạn có một chương trình mà cần thực hiện một tiến trình dài, thì sau đó giá trị của nó để tạo một deamon và chạy nó trong Background.

Lệnh top trong Unix/Linux

Lệnh top là một công cụ rất hữu ích cho việc hiển thị nhanh các tiến trình được sắp xếp bởi các tiêu chuẩn đa dạng.

Nó là một công cụ chẩn đoán tương tác mà cập nhật thường xuyên và hiển thị thông tin về bộ nhớ vật lý và bộ nhớ ảo, sự sử dụng CPU, ….

Dưới đây là cú pháp đơn giản để chạy lệnh top và quan sát kết quả thống kê của sự sử dụng CPU bằng các tiến trình khác nhau:

$top
Job ID với Process ID trong Unix/Linux

Tiến trình Background và Foreground thường được thao tác thông qua Job ID. Số này khác với Process ID và được sử dụng bởi vì nó ngắn hơn.

Ngoài ra, một công việc có thể bao gồm nhiều tiến trình đang chạy trong seri hoặc tại cùng một thời gian, song song, vì thế sử dụng Job ID là dễ dàng hơn theo dõi các tiến trình riêng lẻ.

Bình luận