一、雞肋
1、
二、進程式控制制編程:
1、擷取ID:
(1)擷取本進程ID:pid_t getpid(void);
(2)擷取父進程ID:pid_t getppid(void)
怎麼用:
(1)需要引入標頭檔:#include <sys/types.h>、#include<unistd.h>
2、進程建立-fork:pid_t fork(void);
怎麼用:
(1)fork()後,會產生一個新的子進程,並同時向兩個進程(原來的進程[變成父進程]和建立立的進程)發送傳回值
(2)傳回值,若果fork建立進程成功,則在父進程中會返回子進程的進程代碼pid,同時在新進程中返回0,若建立失敗返回-1
(3)注意:建立的子進程會“複製”父進程中定義的資料和堆棧空間以及其他的一些資訊,再次提醒:子進程是“複製父進程資料的到自己的記憶體空間”,所以子進程對資料的修改不會影響到父進程。
3、進程建立2-vfork: pid_t vfork(void);
怎麼用:
(1)需要引入標頭檔:#include <sys/types.h>、#include<unistd.h>
(2)vfork和fork的區別:
i、
fork: 子進程拷貝父進程的資料區段
vfork: 子進程與父進程共用資料區段
ii、
fork: 父、子進程的執行順序不確定
vfork: 子進程先運行,父進程後運行
4、exec函數族:exec用被執行的程式替換調用它的程式
(1)與fork的區別
i、fork建立一個新的進程,產生一個新的pid
ii、exec啟動一個新程式,替換原有的進程,注意:這裡的替換,是僅僅替換原進程的資料和代碼,其他的不變,因此進程的pid不會改變。
常用的exec函數
(2)int execl(const char * path,const char * arg1,char * arg2,..);
i、需要引入標頭檔:#include<unistd.h>
ii、參數:
path:被執行的程式名(需要包含完整路徑)
arg1~argn:被執行的程式需要的命令列參數,需要包含程式名。以null 指標NULL結束。
iii、eg:execl("/bin/ls","ls","-al","/etc/passwd",(char * )0);
1 2 3 4 5
1表示被執行的程式名,包含完整路徑,
2再寫一遍程式名(不包含路徑,唯寫程式名就可以)
3,4是程式2需要用到的命令列參數
5用null 指標(char * 0)來表示結束
(3)不需要包含路徑的execl的變種:int execlp(const char * paht,const char * arg1,..);
參數:
i、path:被執行的程式名(不包含路徑,將會從$PATH系統內容變數中尋找該程式)
ii、arg1~argn:被執行的程式需要的命令列參數,arg中需要包含程式名。以null 指標NULL結束。
(4)將arg1~argn用數組統一傳入的execl變種:int execv(const char * path,char * const argv[]);
參數:
i、path:被執行的程式名(需要包含完整路徑)
ii、eg:
char * argv{"ls","-al","/etc/passwd",(char * )0};
execv("/bin/ls",argv);
5、system(const char * string);
怎麼用:
(1)調用fork產生子進程,(這裡要注意它和execl不同,它是由子進程來完成工作,而不是像execl那樣用其他程式替換父進程的代碼),然後由子進程來調用,“/bin/sh -c string”,來執行參數string所代表的命令。
(2)需要引入標頭檔:#include <stdlib.h>
6、進程等待:pid_t wait(int * status);
(1)fork建立進程後,父、子進程的執行順序不確定,除了用vfork控制讓子進程先執行外,還有一個更靈活的方法,就是用wait,進程等待函數。
(2)功能:阻塞當前進程,直到它的某個子進程退出,注意這裡是退出,就是即使子進程睡眠,父進程也不會執行。
(3)需要引入標頭檔: #include<sys/types.h>,#include <sys/wait.h>