linux系統編程:進程原語,linux編程進程原語

來源:互聯網
上載者:User

linux系統編程:進程原語,linux編程進程原語

                        進程原語

1. 進程(Process)是電腦中的程式關於某資料集合上的一次運行活動,是系統進行資源分派和調度的基本單位,是作業系統結構的基礎。
2. 進程環境
在libc中定義的全域變數environ指向環境變數表,environ沒有包含在任何標頭檔中,所以在使用時要用extern聲明。用以下代碼可以查看當前進程的所有環境變數的資訊。

#include <stdio.h> int main(void){    extern char **environ;    int i;    for(i = 0; environ[i] != NULL;  i++)    printf("%s\n", environ[i]);    return 0;}

運行結果用索引值對的形式展示環境變數的資訊。幾個常見的環境變數解釋:
PATH:可執行檔的搜尋路徑。
SHELL:當前使用的shell。
HOME:目前使用者的主目錄路徑。
3. 進程狀態
4種主要的進程狀態:運行、就緒、掛起、終止。
4. 進程原語
在liunx中使用函數fork建立新的進程。

#include <unistd.h>pid_t fork(void);

函數特點:調用一次,返回兩次。
在父進程中,返回建立的子進程的pid;在子進程中返回0;出錯,返回-1。
一個建立子進程的執行個體:

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>void sys_err(char *s){    perror(s);    exit(1);}int main(void){    pid_t pid;    pid = fork();    if (pid < 0)        sys_err("fork");    else if (pid > 0)    {        /* parent process */        printf("I am parent,my pid is %d, my parent pid is %d\n", getpid(), getppid());        sleep(1);   //休眠1秒,防止父進程過早退出    }    else    {        /* child process */        printf("I am child,my pid is %d, my parent pid is %d\n", getpid(), getppid());    }    return 0;}//I am child, my pid is 15057, my parent pid is 15056//I am parent, my pid is 15056, my parent pid is 5292
#include <unistd.h>#include <sys/types.h>   //定義了pid_t、uid_t、gid_tpid_t getpid(void);   //擷取當前進程的pidpid_t getppid(void);  //擷取當前進程父進程的piduid_t getuid(void);   //返回實際使用者iduid_t geteuid(void);  //返回有效使用者idgid_t getgid(void);   //返回實際使用者組idgid_t getegid(void);  //返回有效使用者組id

所有id都是正數。
父進程和子進程的關係:
1.子進程複製了父進程的PCB(除了pid)和程式碼片段以及資料區。
2.用fork建立子進程後執行的是和父進程相同的程式(但有可能執行不同的代碼分支),子進程往往要調用一種exec函數以執行另一個程式。當進程調用一種exec函數時,該進程的使用者空間代碼和資料完全被新程式替換,從新程式的啟動常式開始執行。調用exec並不建立新進程,所以調用exec前後該進程的id並未改變。
5. exec族

#include <unistd.h>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 execve(const char *path, char *const argv[], char *const envp[]);

只需弄懂了execl的使用,其它的舉一反三了:path指出了新可執行程式的路徑,後面的arg,即是提供的參數。
使用execl函數更改程式的執行:

//show.c#include <stdio.h>int main(int argc, char **argv){    int i = 0;    while(i < argc)        printf("%s\n", argv[i++]);    return 0;}//app.c#include <stdio.h>#include <unistd.h>#include <stdlib.h>int main(int argc, char **argv){    if(argc < 2)    {        fprintf(stderr, "usage:app newapp ...");        exit(1);    }    printf("zhangxiang\n");    //$ argv[1] zx zhangxiangDavid@126.com    execl(argv[1], "zx", "zhangxiangDavid@126.com", NULL);  //NULL用於指明參數列表的結束    printf("David\n");    return 0;}$ gcc show.c -o show$ gcc app.c -o app$ app showzhangxiangzxzhangxiangDavid@126.com

執行printf(“zhangxiang\n”);了後,程式的程式碼片段被替換,所以原程式的printf(“David\n”);不會被執行。

l 命令列參數列表
p 搜素file時使用path變數
v 使用命令列參數數組
e 使用環境變數數組,不使用進程原有的環境變數,設定新載入程式啟動並執行環境變數
這些函數如果調用成功則載入新的程式從啟動代碼開始執行,不再返回,如果調用出錯則返回-1,所以exec函數只有出錯的傳回值而沒有成功的傳回值。
6. wait()、waitpid()
殭屍進程::子進程退出,父進程沒有回收子進程資源(PCB),則子進程變成殭屍進程。
孤兒進程:父進程先於子進程結束,則子進程成為孤兒進程,子進程的父進程成為1號進程init進程,稱為init進程領養孤兒進程。
子進程結束後,PCB仍然滯留在記憶體。父進程可以通過子進程的PCB來獲知子進程的退出狀態:正常退出時的退出碼、不正常退出時,是被哪個訊號終止的。

#include <sys/types.h>#include <sys/wait.h>pid_t wait(int *status);

函數說明:
參數status為傳出參數,用於記錄退出狀態。
當沒有子進程退出時,wait調用會阻塞當前進程。
成功,返回子進程的pid;
失敗,返回-1;

#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/wait.h>int main(void){    pid_t pid, wpid;    pid = fork();    if(0 == pid)    {        printf("in child\n");        sleep(2);        printf("child exit\n");    }    else if(pid > 0)    {        while(1)        {            wpid = wait(NULL);            printf("in parent %d\n", wpid);            sleep(1);        }    }    else    {        perror("fork");        exit(1);    }    return 0;}//in child//child exit//in parent 27909//in parent -1//in parent -1//^c

wait()會使父進程阻塞,為了不阻塞,需使用waitpid()

#include <sys/types.h>#include <sys/wait.h>pid_t waitpid(pid_t pid, int *status, int options);

函數說明:
pid指明了需回收哪個子進程的PCB;
通過指定options的值,更改函數運行狀態。(特別地,指定WNOHANG,將不會阻塞)。
指定WNOHANG,非阻塞後。若沒有進程退出,返回0,其它同wait。

#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/wait.h>int main(void){    pid_t pid, wpid;    pid = fork();    if(0 == pid)    {        printf("in child\n");        sleep(2);        printf("child exit\n");    }    else if(pid > 0)    {        while(1)        {            wpid = waitpid(0, NULL, WNOHANG);            printf("in parent %d\n", wpid);            sleep(1);        }    }    else    {        perror("fork");        exit(1);    }    return 0;}//in parent 0//in child//in parent 0//child exit//in parent 28700//in parent -1//in parent -1//^c

CCPP Blog 目錄

著作權聲明:本文為博主原創文章,轉載,請註明出處。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.