進程控制(1):進程標識符


    進程標識符(PID)是一個進程的基本屬性,其作用類似於每個人的身份證號碼。根據進程標識符,用戶可以精確地定位一個進程。一個進程標識符唯一對應一個進程,而多個進程標識符可以對應同一個程序。本文將深入探討進程標識符及其相關操作。


1 進程標識符

    每個進程在系統中都有唯一的一個ID標識它,這個ID就是進程標識符(PID)。因為其唯一,所以系統可以根據它准確定位到一個進程。進程標識符的類型為pid_t,其本質上是一個無符號整型的類型別名(typedef)。

    接下來,我們來簡單介紹一個進程與程序的關系。所謂程序,不過是指可運行的二進制代碼文件,把這種文件加載到內存中運行就得到了一個進程。同一個程序文件可以被加載多次成為不同的進程。因此,進程與進程標識符之間是一對一的關系,而與程序文件之間是多對一的關系。

1

在Linux shell中,可以使用ps命令查看當前用戶所使用的進程。

xiaomanon@xiaomanon-machine:~$ ps -u xiaomanon
  PID TTY          TIME CMD
 1296 ?        00:00:00 init
 1357 ?        00:00:00 sh
 1359 ?        00:00:00 sleep
 1362 ?        00:00:01 dbus-daemon
 1371 ?        00:00:00 upstart-event-b
 1375 ?        00:00:00 window-stack-br
 1383 ?        00:00:00 gnome-keyring-d
 1393 ?        00:00:00 upstart-file-br
 1410 ?        00:00:00 bamfdaemon
 1414 ? 00:00:00 upstart-dbus-br 1418 ? 00:00:00 upstart-dbus-br
 1419 ?        00:00:00 ibus-daemon
 1428 ?        00:00:00 gvfsd
 1460 ?        00:00:00 unity-settings-
 1482 ?        00:00:00 hud-service
 1492 ?        00:00:00 at-spi-bus-laun
 1495 ?        00:00:00 gvfsd-fuse
 1497 ?        00:00:00 gnome-session
 1498 ?        00:00:00 dbus-daemon
 1506 ?        00:00:00 ibus-dconf
 1507 ?        00:00:00 ibus-ui-gtk3
 1510 ?        00:00:01 unity-panel-ser
 1512 ?        00:00:00 ibus-x11
 1523 ?        00:00:00 at-spi2-registr
 1600 ?        00:00:00 indicator-messa
 1605 ?        00:00:00 indicator-bluet
 1610 ?        00:00:00 indicator-keybo
 1615 ?        00:00:00 indicator-power
 1625 ?        00:00:00 indicator-datet
 1627 ?        00:00:00 indicator-sound
 1630 ?        00:00:00 indicator-print
 1635 ?        00:00:00 indicator-sessi
 1653 ?        00:00:00 indicator-appli
 1666 ?        00:00:00 evolution-sourc
 1680 ?        00:00:00 pulseaudio
 1733 ?        00:00:00 ibus-engine-sim
 1793 ?        00:00:00 dconf-service
 1795 ?        00:00:00 notify-osd
 1860 ?        00:00:05 compiz
 1901 ?        00:00:00 evolution-calen
 1916 ?        00:00:00 unity-fallback-
 1929 ?        00:00:00 nautilus
 1933 ?        00:00:00 polkit-gnome-au
 1937 ?        00:00:01 nm-applet
 1945 ?        00:00:00 vmtoolsd
 1998 ?        00:00:00 gvfs-udisks2-vo
 2023 ?        00:00:00 gvfs-mtp-volume
 2029 ?        00:00:00 gvfs-afc-volume
 2033 ?        00:00:00 gconfd-2
 2036 ?        00:00:00 gvfs-gphoto2-vo
 2059 ?        00:00:00 gvfsd-trash
 2078 ?        00:00:00 gvfsd-burn
 2100 ?        00:00:00 gvfsd-metadata
 2105 ?        00:00:00 telepathy-indic
 2112 ?        00:00:00 mission-control
 2118 ?        00:00:00 signon-ui
 2126 ?        00:00:00 gnome-terminal
 2132 ?        00:00:00 gnome-pty-helpe
 2133 pts/1    00:00:00 bash
 2182 ?        00:00:00 zeitgeist-datah
 2187 ?        00:00:00 zeitgeist-daemo
 2193 ?        00:00:00 zeitgeist-fts
 2197 ?        00:00:00 cat
 2207 pts/1    00:00:00 ps

    第一列內容是進程標識符(PID),這個標識符是唯一的;最后一列內容是進程的程序文件名。我們可以從中間找到有多個進程對應同一個程序文件名的情況,這是因為有一些常用的程序被多次運行了,比如shell和vi編輯器等。

注意:如果ps命令不使用“-u 用戶名”作為參數,將不能檢查到后台運行的進程。

xiaomanon@xiaomanon-machine:~$ ps
  PID TTY          TIME CMD
 2133 pts/1    00:00:00 bash
 2325 pts/1    00:00:00 ps

 


2 進程中重要的標識符

    每個進程都有6個重要的ID值,分別是:進程ID、父進程ID、有效用戶ID、有效組ID、實際用戶ID和實際組ID。這6個ID保存在內核中的數據結構中,有些時候用戶程序需要得到這些ID。

    例如,在/proc文件系統中,每一個進程都擁有一個子目錄,里面存有進程的信息。當使用進程讀取這些文件時,應該先得到當前進程的ID才能確定進入哪一個進程的相關子目錄。由於這些ID存儲在內核之中,因此,Linux提供一組專門的接口函數來訪問這些ID值。

    Linux環境下分別使用getpid()和getppid()函數來得到進程ID和父進程ID,分別使用getuid()和geteuid()函數來得到進程的用戶ID和有效用戶ID,分別使用getgid()和getegid()來獲得進程的組ID和有效組ID,其函數原型如下:

#include <unistd.h>
pid_t getpid(void);    //獲取進程ID
pid_t getppid(void);  //獲取父進程ID

uid_t getuid(void);    //獲取用戶ID
uid_t geteuid(void);    //獲取有效用戶ID

gid_t getgid(void);    //獲取組ID
gid_t getegid(void);    //獲取有效組ID

    以上6個函數,如果執行成功,則返回對應的ID值;失敗,則返回-1。除了進程ID和父進程ID這兩個值不能夠更改以外,其他的4個ID值在適當的條件下可以被更改。下面的示例程序用於獲取當前進程的6個ID值並打印出來。

//Get ID information about current process
#include <stdio.h>
#include <unistd.h>

int main(void)
{
    printf("PID: %u\n", getpid());
    printf("PPID: %u\n", getppid());
    printf("UID: %u\n", getuid());
    printf("EUID: %u\n", geteuid());
    printf("GID: %u\n", getgid());
    printf("EGID: %u\n", getegid());

    return 0;
}

程序運行效果如下:

xiaomanon@xiaomanon-machine:~/Documents/c_code$ ./getid 
PID: 2681
PPID: 2133
UID: 1000
EUID: 1000
GID: 1000
EGID: 1000

 


3 參考文獻

[1] 吳岳,Linux C程序設計大全,清華大學出版社


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM