Linux程序設(shè)計(jì)入門 系統(tǒng)進(jìn)程的詳細(xì)介紹
1、進(jìn)程的概念
Linux操作系統(tǒng)是面向多用戶的.在同一時(shí)間可以有許多用戶向操作系統(tǒng)發(fā)出各種命令.那么操作系統(tǒng)是怎么實(shí)現(xiàn)多用戶的環(huán)境呢? 在現(xiàn)代的操作系統(tǒng)里面,都有程序和進(jìn)程的概念.那么什么是程序,什么是進(jìn)程呢? 通俗的講程序是一個(gè)包含可以執(zhí)行代碼的文件,是一個(gè)靜態(tài)的文件.而進(jìn)程是一個(gè)開(kāi)始執(zhí)行但是還沒(méi)有結(jié)束的程序的實(shí)例.就是可執(zhí)行文件的具體實(shí)現(xiàn). 一個(gè)程序可能有許多進(jìn)程,而每一個(gè)進(jìn)程又可以有許多子進(jìn)程.依次循環(huán)下去,而產(chǎn)生子孫進(jìn)程. 當(dāng)程序被系統(tǒng)調(diào)用到內(nèi)存以后,系統(tǒng)會(huì)給程序分配一定的資源(內(nèi)存,設(shè)備等等)然后進(jìn)行一系列的復(fù)雜操作,使程序變成進(jìn)程以供系統(tǒng)調(diào)用.在系統(tǒng)里面只
有進(jìn)程沒(méi)有程序,為了區(qū)分各個(gè)不同的進(jìn)程,系統(tǒng)給每一個(gè)進(jìn)程分配了一個(gè)ID(就象我們的身份證)以便識(shí)別. 為了充分的利用資源,系統(tǒng)還對(duì)進(jìn)程區(qū)分了不同的狀態(tài).將進(jìn)程分為新建,運(yùn)行,阻塞,就緒和完成五個(gè)狀態(tài). 新建表示進(jìn)程正在被創(chuàng)建,運(yùn)行是進(jìn)程正在運(yùn)行,阻塞是進(jìn)程正在等待某一個(gè)事件發(fā)生,就緒是表示系統(tǒng)正在等待CPU來(lái)執(zhí)行命令,而完成表示進(jìn)程已經(jīng)結(jié)束了系統(tǒng)正在回收資源. 關(guān)于進(jìn)程五個(gè)狀態(tài)的詳細(xì)解說(shuō)我們可以看《操作系統(tǒng)》上面有詳細(xì)的解說(shuō)。
2、進(jìn)程的標(biāo)志
上面我們知道了進(jìn)程都有一個(gè)ID,那么我們?cè)趺吹玫竭M(jìn)程的ID呢?系統(tǒng)調(diào)用getpid可以得到進(jìn)程的ID,而getppid可以得到父進(jìn)程(創(chuàng)建調(diào)用該函數(shù)進(jìn)程的進(jìn)程)的ID.
#include <unistd> pid_t getpid(void); pid_t getppid(void);
進(jìn)程是為程序服務(wù)的,而程序是為了用戶服務(wù)的.系統(tǒng)為了找到進(jìn)程的用戶名,還為進(jìn)程和用戶建立聯(lián)系.這個(gè)用戶稱為進(jìn)程的所有者.相應(yīng)的每一個(gè)用戶也有一個(gè)用戶ID.通過(guò)系統(tǒng)調(diào)用getuid可以得到進(jìn)程的所有者的ID.由于進(jìn)程要用到一些資源,而Linux對(duì)系統(tǒng)資源是進(jìn)行保護(hù)的,為了獲取一定資源進(jìn)程還有一個(gè)有效用戶ID.這個(gè)ID和系統(tǒng)的資源使用有關(guān),涉及到進(jìn)程的權(quán)限. 通過(guò)系統(tǒng)調(diào)用geteuid我們可以得到進(jìn)程的有效用戶ID. 和用戶ID相對(duì)應(yīng)進(jìn)程還有一個(gè)組ID和有效組ID系統(tǒng)調(diào)用getgid和getegid可以分別得到組ID和有效組ID。
#include <unistd> #include <sys/types.h> uid_t getuid(void); uid_t geteuid(void); gid_t getgid(void); git_t getegid(void);
有時(shí)候我們還會(huì)對(duì)用戶的其他信息感興趣(登錄名等等),這個(gè)時(shí)候我們可以調(diào)用getpwui
d來(lái)得到。
struct passwd { char *pw_name; /* 登錄名稱 */ char *pw_passwd; /* 登錄口令 */ uid_t pw_uid; /* 用戶ID */ gid_t pw_gid; /* 用戶組ID */ char *pw_gecos; /* 用戶的真名 */ char *pw_dir; /* 用戶的目錄 */ char *pw_shell; /* 用戶的SHELL */ }; #include <pwd.h> #include <sys/types.h> struct passwd *getpwuid(uid_t uid);
下面我們學(xué)習(xí)一個(gè)實(shí)例來(lái)實(shí)踐一下上面我們所學(xué)習(xí)的幾個(gè)函數(shù):
#include <unistd.h> #include <pwd.h> #include <sys/types.h> #include <stdio.h> int main(int argc,char **argv) { pid_t my_pid,parent_pid; uid_t my_uid,my_euid; gid_t my_gid,my_egid; struct passwd *my_info; my_pid=getpid(); parent_pid=getppid(); my_uid=getuid(); my_euid=geteuid(); my_gid=getgid(); my_egid=getegid(); my_info=getpwuid(my_uid); printf('Process ID:%ld ',my_pid); printf('Parent ID:%ld ',parent_pid); printf('User ID:%ld ',my_uid); printf('Effective User ID:%ld ',my_euid); printf('Group ID:%ld ',my_gid); printf('Effective Group ID:%ld ',my_egid): if(my_info) { printf('My Login Name:%s ' ,my_info->pw_name); printf('My Password :%s ' ,my_info->pw_passwd); printf('My User ID :%ld ',my_info->pw_uid); printf('My Group ID :%ld ',my_info->pw_gid); printf('My Real Name:%s ' ,my_info->pw_gecos); printf('My Home Dir :%s ', my_info->pw_dir); printf('My Work Shell:%s ', my_info->pw_shell); } }
3、進(jìn)程的創(chuàng)建
創(chuàng)建一個(gè)進(jìn)程的系統(tǒng)調(diào)用很簡(jiǎn)單.我們只要調(diào)用fork函數(shù)就可以了.
#include <unistd.h> pid_t fork();
當(dāng)一個(gè)進(jìn)程調(diào)用了fork以后,系統(tǒng)會(huì)創(chuàng)建一個(gè)子進(jìn)程.這個(gè)子進(jìn)程和父進(jìn)程不同的地方只有他的進(jìn)程ID和父進(jìn)程ID,其他的都是一樣.就象符進(jìn)程克隆(clone)自己一樣.當(dāng)然創(chuàng)建兩個(gè)一模一樣的進(jìn)程是沒(méi)有意義的.為了區(qū)分父進(jìn)程和子進(jìn)程,我們必須跟蹤fork的返回值. 當(dāng)fork掉用失敗的時(shí)候(內(nèi)存不足或者是用戶的最大進(jìn)程數(shù)已到)fork返回-1,否則fork的返回值有重要的作用.對(duì)于父進(jìn)程fork返回子進(jìn)程的ID,而對(duì)于fork子進(jìn)程返回0.我們就是根據(jù)這個(gè)返回值來(lái)區(qū)分父子進(jìn)程的. 父進(jìn)程為什么要?jiǎng)?chuàng)建子進(jìn)程呢?前面我們已經(jīng)說(shuō)過(guò)了Linux是一個(gè)多用戶操作系統(tǒng),在同一時(shí)間會(huì)有許多的用戶在爭(zhēng)奪系統(tǒng)的資源.有時(shí)進(jìn)程為了早一點(diǎn)完成任務(wù)就創(chuàng)建子進(jìn)程來(lái)爭(zhēng)奪資源. 一旦子進(jìn)程被創(chuàng)建,父子進(jìn)程一起從fork處繼續(xù)執(zhí)行,相互競(jìng)爭(zhēng)系統(tǒng)的資源.有時(shí)候我們希望子進(jìn)程繼續(xù)執(zhí)行,而父進(jìn)程阻塞直到子進(jìn)程完成任務(wù).這個(gè)時(shí)候我們可以調(diào)用wait或者waitpid系統(tǒng)調(diào)用.
#include <sys/types.h> #include <sys/wait.h> pid_t wait(int *stat_loc); pid_t waitpid(pid_t pid,int *stat_loc,int options);
