Bài 40.124 phút đọc
Tiến trình, PID, và /proc
Sau bài này bạn sẽ làm được
- Kể các thành phần của một tiến trình
- Lấy PID, PPID, UID bằng lời gọi hệ thống
- Đọc thông tin tiến trình qua /proc
- Phân biệt chương trình với tiến trình
Phần này nói chuyện trực tiếp với hệ điều hành. Trước khi tạo, thay, hay chờ một tiến trình, phải biết một tiến trình gồm những gì. Bài này mở nó ra và nhìn vào bên trong qua /proc.
#Tiến trình là gì
Tiến trình
Một chương trình đang chạy. Nó gồm mã lệnh, dữ liệu, ngăn xếp, heap, bảng mô tả tệp, và một không gian địa chỉ riêng mà không tiến trình khác nhìn thấy được.
Tien trinh (mot khong gian dia chi rieng)
+-------------------------------------------+
| ma lenh (.text) chi doc |
| du lieu (.data .bss) bien toan cuc |
| heap malloc lon len -> |
| ... |
| <- ngan xep lon xuong bien cuc bo |
+-------------------------------------------+
| bang mo ta tep: 0 stdin, 1 stdout, ... |
+-------------------------------------------+
/* Moi tien trinh co bang mo ta tep RIENG va khong gian dia chi
RIENG. Hai tien trinh cung chay mot chuong trinh van la hai
khong gian dia chi tach biet: sua bien trong cai nay khong
anh huong cai kia. Do la khac biet co ban voi luong (Chuong 45),
noi cac luong CHIA SE khong gian dia chi. */#PID và họ hàng
Lấy PID, PPID, UID
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void) {
pid_t pid = getpid(); /* PID cua CHINH tien trinh nay */
pid_t ppid = getppid(); /* PID cua tien trinh CHA */
uid_t uid = getuid(); /* ID nguoi dung so huu */
printf("PID = %d\n", pid);
printf("PPID = %d\n", ppid);
printf("UID = %d\n", uid);
return 0;
}terminal
gcc pid.c -o pid && ./pid
PID = 24817 PPID = 3921 UID = 1000
# Chay lai: PID doi (moi lan chay la mot tien trinh moi)
./pid
PID = 24831 PPID = 3921 UID = 1000
| Lời gọi | Trả về |
|---|---|
| getpid() | PID của chính tiến trình |
| getppid() | PID của tiến trình cha |
| getuid() | ID người dùng thật |
| geteuid() | ID người dùng hiệu lực, khác uid khi setuid |
| getgid() | ID nhóm |
#Nhìn vào /proc
/proc
Một hệ tệp ảo của Linux. Mỗi tiến trình có một thư mục
/proc/PID/ chứa thông tin về nó dưới dạng tệp đọc được. Không phải tệp thật trên đĩa; nhân sinh ra nội dung khi bạn đọc. /proc/self/ luôn trỏ tới tiến trình đang đọc.terminal
# Thong tin tien trinh hien tai
cat /proc/self/status | head -8
Name: cat Umask: 0022 State: R (running) Tgid: 24902 Pid: 24902 PPid: 3921 TracerPid: 0 Uid: 1000 1000 1000 1000
# Cac mo ta tep dang mo (0,1,2 la stdin,stdout,stderr)
ls -l /proc/self/fd
lrwx------ 0 -> /dev/pts/2 lrwx------ 1 -> /dev/pts/2 lrwx------ 2 -> /dev/pts/2 lr-x------ 3 -> /proc/24902/fd
#Chương trình và tiến trình
Tự làm thử
- Viết chương trình in PID, PPID, UID và chạy nó vài lần, quan sát PID đổi.
- Đọc
/proc/self/statusvà tìm dòng bộ nhớ đang dùng (VmRSS). - Đếm số mô tả tệp trong
/proc/self/fdvà giải thích tại sao có bốn cái. - Chạy
pstreevà tìm chương trình của bạn trong cây. - Mở
/proc/self/mapsvà tìm vùng ngăn xếp cùng vùng heap. - Giải thích khác biệt giữa
getuidvàgeteuidcho một chương trìnhsetuid.
Trình chấm điểm tự động sẽ được bổ sung ở giai đoạn sau. Hiện tại bạn tự chạy thử trên máy.
Tóm tắt
- Tiến trình là chương trình đang chạy, có không gian địa chỉ và bảng mô tả tệp riêng.
getpid,getppid,getuidcho biết tiến trình là ai và con của ai; mỗi tiến trình có đúng một cha./proc/PID/là cửa sổ nhìn vào một tiến trình;/proc/self/fdlà công cụ tìm rò rỉ mô tả tệp.- Một chương trình trên đĩa có thể sinh nhiều tiến trình, mỗi cái độc lập.
- Unix tách tạo tiến trình (
fork) khỏi thay chương trình (exec); Windows gộp chúng, nên MinGW không cófork.