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

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


1 進程標識符

    每一個進程在系統中都有惟一的一個ID標識它,這個ID就是進程標識符(PID)。由於其惟一,因此係統能夠根據它準肯定位到一個進程。進程標識符的類型爲pid_t,其本質上是一個無符號整型的類型別名(typedef)。bash

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

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編輯器等。app

注意:若是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值。ui

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

#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程序設計大全,清華大學出版社

相關文章
相關標籤/搜索