★進程標識符
每個進程都有非負的整形表示唯一的進程ID。下面是一些標識符:
pid:調用進程的ID(獲取方式getpid)
ppid:調用進程的父進程ID(獲取方式getppid)
uid:調用進程的實際用戶ID(獲取方式getuid)
euid:調用進程的有效用戶ID(獲取方式getuid)
gid:調用進程的實際組ID(獲取getgid)
egid:調用進程的有效組ID(獲取getegid)
例:用fork創建子進程,查看父子進程的pid、ppid、uid、euid。
運行結果:
★進程創建
上篇博客中提到可以使用fork( )和execve( )來創建,我們能夠知道fork後的子進程能夠獲得父進程的數據空間、堆、棧的副本,父子進程同時共享文本段。所以說:子進程不能改變父進程中某個變量的值,內核只能修改內存副本中該變量的值。
例:
運行結果:
由上面的程序結果能夠看到,子進程對變量的值進行更改,但是並沒有影響到父進程中變量的值。一般父進程和子進程執行的先後順序是不確定的,取決於系統的調度算法。上面的程序父進程先sleep,使得子進程先執行。
這裏再介紹一下vfork( )函數,vfork和fork都能夠創建一個子進程,但是vfork的子進程不會將父進程的地址空間進行復制,所以子進程會先執行,在其調用exec後或者exit後,父進程纔可以執行。
例:
運行結果:
★進程等待
進程等待可以使用兩個函數wait和waitpid。調用之後會產生以下的一些情況:
(1)如果所有的子進程都處於運行狀態,則會阻塞。
(2)如果一個子進程已經終止,正在等待父進程獲取其狀態,則取得該子進程的終止狀態立即返回。
(3)如果它沒有任何的子進程,則立即出錯返回。
頭文件:#include <sys/types.h> #include <sys/wait.h>
① pid_t wait (int* status);
②pid_t waitpid(pid_t pid, int* status, int options);
wait函數如果成功,則返回被等待進程的pid,失敗返回-1,waitpid函數正常返回收集到的子進程的ID,失敗返回-1.