进程函数一步步理解Linux进程(2)--进程编程进程函数
生活随笔
收集整理的這篇文章主要介紹了
进程函数一步步理解Linux进程(2)--进程编程进程函数
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
查了好多資料,發(fā)現(xiàn)還是不全,干脆自己整理吧,至少保證在我的做法正確的,以免誤導(dǎo)讀者,也是給自己做個(gè)記錄吧!
????
0. 說明????
????
作者:Gao Peng<gaopenghigh@gmail.com>????
本文章由Gao Peng編寫,轉(zhuǎn)載請注明出處。????
原文址地: http://blog.csdn.net/gaopenghigh/article/details/8829832????
????
????
1. 獲得各種ID????
????
在“一步步懂得Linux進(jìn)程(1)--基礎(chǔ)知識(shí)”中我們論討了幾種ID:PID, PPID, PGID, SID。另外Linux中還有用戶ID(UID), 效有用戶ID(EUID), 用戶組ID(GID), 效有用戶組ID(EGID)等,面下這些函數(shù)恰是用來獲得這些ID: #include <unistd.h> pid_t getpid(void); pid_t getppid(void); pid_t getpgid(pid_t pid); /* pid為0時(shí)則返回用調(diào)進(jìn)程的進(jìn)程組ID */ pid_t getsid(pid_t pid); /* pid為0時(shí)則返回用調(diào)進(jìn)程的會(huì)話首進(jìn)程的ID */ uid_t getuid(void); uid_t geteuid(void); gid_t getgid(void); gid_t getegid(void);????
????
2. fork函數(shù)????
????
fork函數(shù)多是Linux中最著名的函數(shù)了。一個(gè)現(xiàn)有進(jìn)程可以用調(diào)fork函數(shù)建創(chuàng)一個(gè)新進(jìn)程。 #include <unistd.h> pid_t fork(void);很有意思的是,用調(diào)fork函數(shù)時(shí),生產(chǎn)了子進(jìn)程,而fork函數(shù)分別在父進(jìn)程和子進(jìn)程中都有返回,其中在父進(jìn)程中返回子進(jìn)程的PID,子進(jìn)程中則返回0。子進(jìn)程中的一切都是從父進(jìn)程copy去過的(事實(shí)上,Linux用了“寫時(shí)復(fù)制”的技巧,也就是指直到真正對數(shù)據(jù)生產(chǎn)寫操縱時(shí),這些資源才真的被copy)。fork的一個(gè)用使示例如下: #include <unistd.h> #include <stdio.h> int main(void) { int var = 10;pid_t pid;if ((pid = fork()) < 0) {printf("fork error\n");} else if (pid == 0) { /* child */printf("in child, ");var++;} else { /* parent */printf("in parent, ");var--;}printf("pid=%d, ppid=%d, var=%d\n", getpid(), getppid(), var);return 0; }
編譯并運(yùn)行這個(gè)序程: $ gcc -Wall fork_test.c $./a.out in parent, pid=21319, ppid=18586, var=9 in child, pid=21320, ppid=21319, var=11
正如我們想預(yù)的那樣,變量var分別在父進(jìn)程和子進(jìn)程中被-1和+1。
????
????
????
3. exit函數(shù)和atexit函數(shù)????
????
3.1 exit????
有3個(gè)函數(shù)用于畸形止終一個(gè)序程: #include <stdlib.h> void exit(int status); void _Exit(int status); #include <unistd.h> void _exit(int status);其中,_exit和_Exit直接進(jìn)入核內(nèi),exit則是先用調(diào)執(zhí)行各止終處置序程(exit handler),然后關(guān)閉全部準(zhǔn)標(biāo)IO流,最后才進(jìn)入核內(nèi)。三個(gè)函數(shù)中,參數(shù)status都表現(xiàn)止終狀態(tài)。 子進(jìn)程止終時(shí),核內(nèi)并沒有全完抹去這個(gè)進(jìn)程的一切,而是保存以必定的信息,比如PID,止終狀態(tài),用使的CPU間時(shí)總量等等。父進(jìn)程可以通過wait系列函數(shù)獲得到這些信息,然后再根據(jù)實(shí)際需要做更多的處置。在子進(jìn)程已結(jié)束但父進(jìn)程還沒有去獲得這些信息這段間時(shí)內(nèi),子進(jìn)程叫做僵尸進(jìn)程(zombie process)。 每日一道理
今天陽光很好,坐在窗前,看窗外如此晴朗的天感覺特別舒心,雨過天晴后的世界總給人一種明媚,仿佛陽光照耀在“心田”上空,讓前些天被風(fēng)雨踐踏的花朵重新得到愛的關(guān)懷,重現(xiàn)生命的活力!
????
子進(jìn)程和父進(jìn)程獨(dú)立運(yùn)行,但當(dāng)子進(jìn)程止終時(shí),統(tǒng)系會(huì)給父進(jìn)程發(fā)送一個(gè)SIGCHLD信號(hào),父進(jìn)程可以捕獲這個(gè)信號(hào)并做響應(yīng)的處置,但Linux中默許對次信號(hào)疏忽。????
????
3.2 atexit????
面前說過,exit函數(shù)會(huì)先用調(diào)執(zhí)行各止終處置序程(exit handler)。這些止終處置序程,恰是通過atexit函數(shù)冊注的: #include <stdlib.h> int atexit(void (*func)(void));其中,atexit的參數(shù)是一個(gè)函數(shù)址地,用調(diào)此函數(shù)時(shí)無需送傳任何參數(shù),也不期望它返回一個(gè)值。一個(gè)進(jìn)程可以冊注32個(gè)止終處置序程,exit用調(diào)這些函數(shù)的序順與它們冊注的序順相反。
????
????
4. wait系列函數(shù)
4.1 wait和waitpid函數(shù) 子進(jìn)程止終后,核內(nèi)仍然保存該進(jìn)程的一些信息,這些信息可以通過wait和waitpid函數(shù)來獲得。 #include <sys/wait.h> pid_t wait(int *statloc); pid_t waitpid(pid_t pid, int *statloc, int options);
這兩個(gè)函數(shù)若執(zhí)行功成則返回進(jìn)程PID或者0,錯(cuò)出則返回-1。
執(zhí)行這兩個(gè)函數(shù)時(shí), a. 如果其全部子進(jìn)程都還在運(yùn)行,則阻塞,直到有子進(jìn)程止終; b. 如果沒有子進(jìn)程,則錯(cuò)出返回-1; c. 如果一個(gè)子進(jìn)程已止終并等待父進(jìn)程獲得其止終狀態(tài),則取得其PID當(dāng)即返回; 參數(shù)statloc是形整指針,當(dāng)該參數(shù)不為NULL時(shí),子進(jìn)程的止終狀態(tài)就存入該指針指向的元單內(nèi)。
waitpid和wait的的區(qū)分是: a. waitpid可以等待一個(gè)指定的進(jìn)程止終,所等待的進(jìn)程由參數(shù)pid供給: pid == -1 ? 等待任一子進(jìn)程 pid > 0 ? ? 等待進(jìn)程PID與pid等相的進(jìn)程,若不存在,則錯(cuò)出返回 pid == 0 ? ?等待PGID于等用調(diào)進(jìn)程PGID的任一子進(jìn)程 pid < 0 ? ? 等待其PGID于等pid絕對值的任一子進(jìn)程 b. waitpid中的第三個(gè)參數(shù)options,options可所以0,也可所以以下三個(gè)值按位“或”的結(jié)果: WCONTINUED ?由pid指定的進(jìn)程在暫停后繼承,且未尚告報(bào)其狀態(tài),則返回其狀態(tài) WNOHANG ? ? waitpid不阻塞,返回0 WUNTRACED ? 由pid指定的進(jìn)程處于暫停狀態(tài),且該狀態(tài)為告報(bào)過,則返回其狀態(tài)
4.2 waitid函數(shù) 可以看到,waitpid函數(shù)中參數(shù)pid的用作夠不純粹,增加了代碼的復(fù)雜度,降低了可讀性。waitid函數(shù)與waitpid似類,但waitid用獨(dú)自的參數(shù)表現(xiàn)要等待的子進(jìn)程的類型。 #include <unistd.h> int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
詳細(xì)用使方法可考參waitid的man手冊。
4.3 wait4函數(shù) 與wait, waitpid, waitid比相,wait4函數(shù)多了一個(gè)能功:要求核內(nèi)返回進(jìn)程用使的資源匯總。詳細(xì)可考參wait4的man手冊。
5. exec系列函數(shù)
????
????
當(dāng)進(jìn)程用調(diào)一種exec函數(shù)時(shí),改進(jìn)程執(zhí)行的序程全完替換為新序程,新序程由exec函數(shù)的參數(shù)指定。 #include <unistd.h> extern char **environ; int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char *arg, ...); int execle(const char *path, const char *arg, ..., char * const envp[]); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); int execvpe(const char *file, char *const argv[], char *const envp[]);可以用exec函數(shù)中的母字l, v, p, e對這6個(gè)函數(shù)做區(qū)分: l ? ?表現(xiàn)list,要求將新序程的個(gè)每命令行參數(shù)都表現(xiàn)為一個(gè)獨(dú)立的參數(shù)
????
v ? ?表現(xiàn)vector,與list對應(yīng),先造構(gòu)一個(gè)指向全部參數(shù)的指針數(shù)組,然后把該數(shù)組址地作為參數(shù)傳給exec????
p ? ?表現(xiàn)用使file作為參數(shù),在PATH中找尋對應(yīng)的文件,file中含有"/"則視作徑路????
e ? ?表現(xiàn)可以傳遞一個(gè)指向境環(huán)字符串指針數(shù)組的指針,指向的字符串作為境環(huán)變量????
????
考參資料:
????
《UNIX境環(huán)級(jí)高編程》????
“UNIX進(jìn)程揭秘”? http://www.ibm.com/developerworks/cn/aix/library/au-unixprocess.html文章結(jié)束給大家分享下程序員的一些笑話語錄: 姿勢要豐富,經(jīng)常上百度!
轉(zhuǎn)載于:https://www.cnblogs.com/jiangu66/archive/2013/04/21/3033360.html
總結(jié)
以上是生活随笔為你收集整理的进程函数一步步理解Linux进程(2)--进程编程进程函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET操作Excel(终极方法N
- 下一篇: 基于json的jquery地区联动