Linux進(jìn)程

進(jìn)程的控制

什么是進(jìn)程

狹義上來說進(jìn)程是操作系統(tǒng)上運(yùn)行的一個(gè)程序。

廣義上來說進(jìn)程是一個(gè)具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合的一次運(yùn)行活動(dòng)。它是操作系統(tǒng)動(dòng)態(tài)執(zhí)行的基本單元,在傳統(tǒng)的操作系統(tǒng)中,進(jìn)程既是基本的分配單元,也是基本的執(zhí)行單元。

進(jìn)程控制是進(jìn)程管理中最基本的功能。它用于創(chuàng)建一個(gè)新進(jìn)程,終止一個(gè)已完成的進(jìn)程,或者去終止一個(gè)因出現(xiàn)某事件而使其無法運(yùn)行下去的進(jìn)程,還可負(fù)責(zé)進(jìn)程運(yùn)行中的狀態(tài)轉(zhuǎn)換。

Linux系統(tǒng)上進(jìn)程的幾種狀態(tài):

  • 運(yùn)行狀態(tài):進(jìn)程正在運(yùn)行,或者在運(yùn)行隊(duì)列中等待運(yùn)行。
  • 可中斷等待狀態(tài):進(jìn)程在等待某個(gè)事件的完成,在等待中不可以被信號(hào)或定時(shí)器喚醒,必須等待直到等待的事情發(fā)生。
  • 僵死狀態(tài):進(jìn)程已經(jīng)終止,但是進(jìn)程的描述符還在,直到父進(jìn)程的wait函數(shù)釋放。
  • 停止?fàn)顟B(tài):進(jìn)程收到系統(tǒng)發(fā)出的信號(hào)(SIGSTOP SIFTOP SIGTIN SIGTOU )之后停止運(yùn)行或者該進(jìn)程正在被跟蹤(調(diào)試應(yīng)用程序gdb,進(jìn)程處于跟蹤狀態(tài))。

進(jìn)程的創(chuàng)建

進(jìn)程的創(chuàng)建一是操作系統(tǒng)來創(chuàng)建。二是由父進(jìn)程創(chuàng)建。

  • 使用fork函數(shù)來分配一個(gè)新的進(jìn)程。

    函數(shù) 函數(shù)頭文件 函數(shù)原型 函數(shù)功能
    fork #include<sys/types> & #include <unistd.h> pid_t fork(void) 創(chuàng)建一個(gè)新的子進(jìn)程,繼承原有進(jìn)程(父進(jìn)程)的很多屬性``(用戶ID 組ID 當(dāng)前工作環(huán)境 等等)
    vfork #include<sys/types> & #include <unistd.h> pid_t vfork(void) 類似fork但是使用vfork時(shí)系統(tǒng)會(huì)讓子進(jìn)程共享父進(jìn)程的地址空間,父進(jìn)程與子進(jìn)程的操作互相可見。
    函數(shù) 相同 不同
    fork 都是創(chuàng)建一個(gè)子進(jìn)程 占用資源的不同,fork占用較大的系統(tǒng)資源,fork一個(gè)新的進(jìn)程會(huì)將父進(jìn)程的很多都會(huì)復(fù)制,增大了消耗
    vfork 子進(jìn)程完全運(yùn)行在父進(jìn)程的地址空間上,子進(jìn)程對(duì)于父進(jìn)程的改變都變得可見。
函數(shù) 相對(duì)于父進(jìn)程來說
fork 父進(jìn)程與子進(jìn)程運(yùn)行的順序不一定,父進(jìn)程與子進(jìn)程運(yùn)行的時(shí)候,兩個(gè)會(huì)搶系統(tǒng)的調(diào)用時(shí)間。
vfork 子進(jìn)程先比父進(jìn)程運(yùn)行,等子進(jìn)程運(yùn)行完之后,父進(jìn)程再運(yùn)行。

創(chuàng)建守護(hù)進(jìn)程

什么是守護(hù)進(jìn)程?這是一段來自維基百科的描述。

  • 在一個(gè)多任務(wù)的電腦操作系統(tǒng)中,守護(hù)進(jìn)程(英語:daemon)是一種在后臺(tái)執(zhí)行的電腦程序。此類程序會(huì)被以進(jìn)程的形式初始化。守護(hù)進(jìn)程程序的名稱通常以字母“d”結(jié)尾:例如,syslogd就是指管理系統(tǒng)日志的守護(hù)進(jìn)程。

    通常,守護(hù)進(jìn)程沒有任何存在的父進(jìn)程(即PPID=1),且在UNIX系統(tǒng)進(jìn)程層級(jí)中直接位于init之下。守護(hù)進(jìn)程程序通常通過如下方法使自己成為守護(hù)進(jìn)程:對(duì)一個(gè)子進(jìn)程運(yùn)行fork,然后使其父進(jìn)程立即終止,使得這個(gè)子進(jìn)程能在init下運(yùn)行。這種方法通常被稱為“脫殼”。

    系統(tǒng)通常在啟動(dòng)時(shí)一同起動(dòng)守護(hù)進(jìn)程。守護(hù)進(jìn)程為對(duì)網(wǎng)絡(luò)請(qǐng)求,硬件活動(dòng)等進(jìn)行響應(yīng),或其他通過某些任務(wù)對(duì)其他應(yīng)用程序的請(qǐng)求進(jìn)行回應(yīng)提供支持。守護(hù)進(jìn)程也能夠?qū)τ布M(jìn)行配置(如在某些Linux系統(tǒng)上的devfsd),運(yùn)行計(jì)劃任務(wù)(例如cron),以及運(yùn)行其他任務(wù)。

  • Linux創(chuàng)建一個(gè)守護(hù)進(jìn)程創(chuàng)建

孤兒進(jìn)程與僵尸進(jìn)程

  • 當(dāng)父進(jìn)程先于子進(jìn)程退出時(shí),子進(jìn)程會(huì)被init或這systemd接收為子進(jìn)程。這一過程亦被稱為收養(yǎng),雖然有PID為1的系統(tǒng)進(jìn)程當(dāng)做父進(jìn)程,但是創(chuàng)建他的父進(jìn)程已經(jīng)被系統(tǒng)回收了。

    Ubuntu 18.04 LTS的環(huán)境下時(shí),收養(yǎng)的父進(jìn)程為圖形界面的進(jìn)程。只有進(jìn)入字符界面運(yùn)行時(shí),對(duì)應(yīng)收養(yǎng)的父進(jìn)程才為1

  • 創(chuàng)建孤兒進(jìn)程與孤兒進(jìn)程

    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <stdio.h>
    //孤兒進(jìn)程,父進(jìn)程先于子進(jìn)程退出。
    int main(void){
        int pid;
        pid = fork();
        if(pid == 0){
            printf("I am child process.\n");
            sleep(5);
            //確保子進(jìn)程后于父進(jìn)程退出,子進(jìn)程由系統(tǒng)收養(yǎng)并wait掉。
        }
        if(pid > 0){
            printf("I am father process.\n");
            sleep(1);
        }
        return 0;
    }
    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <stdio.h>
    //孤兒進(jìn)程,父進(jìn)程先于子進(jìn)程退出。
    int main(void){
        int pid;
        pid = fork();
        if(pid == 0){
            printf("I am child process.\n");
            exit(0);
        }
        //死循環(huán),父進(jìn)程沒有使用wait函數(shù)等待子進(jìn)程運(yùn)行,沒有人清理將是進(jìn)程。
        if(pid > 0){
            printf("I am father process.\n");
            while(1){}
        }
        return 0;
    }
    

wait 和 waitpid

  • waitwaitpid

    原型 作用
    pid_t wait(int *statloc); 父進(jìn)程暫停,等待子進(jìn)程結(jié)束
    pid_t waitpid(pid_t pid, int *statloc, int options); 父進(jìn)程暫停,等到特定的子進(jìn)程結(jié)束

進(jìn)程的退出

正常退出 異常退出
調(diào)用函數(shù)exit\_exit 調(diào)用about函數(shù)或者由系統(tǒng)發(fā)出signal退出。

exit()與_ecit()的區(qū)別

函數(shù) 區(qū)別
exit() 調(diào)用該函數(shù)后,系統(tǒng)會(huì)先執(zhí)行一些清除操作,然后返還給內(nèi)核。
_exit() 調(diào)用該函數(shù)后,馬上拋給內(nèi)核。

exit與return的區(qū)別

區(qū)別 操作
exit exit用于結(jié)束一個(gè)程序
return return用于函數(shù),返回后回到調(diào)用的上一層函數(shù)

exit的參數(shù),正常退出參數(shù)為0,異常退出參數(shù)為非零值

執(zhí)行新的程序

  • 父進(jìn)程fork一個(gè)子進(jìn)程后,使用exec函數(shù)來調(diào)用另外的可執(zhí)行程序代替當(dāng)前進(jìn)程的可執(zhí)行映像。

    進(jìn)程一旦調(diào)用exec函數(shù)后,相當(dāng)于將原有的進(jìn)程殺死,只保留進(jìn)程ID,對(duì)于系統(tǒng)而言,同樣的進(jìn)程,執(zhí)行的操作不一樣了。

  • exec函數(shù)家族

    **int execl(const char path, const char arg, ...
    */ (char ) NULL /);

    **int execlp(const char file, const char arg, ...
    */ (char ) NULL /);

    **int execle(const char path, const char arg, ...
    */, (char ) NULL, 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[]);

  • 例子:

    被調(diào)用的文件

    調(diào)用的文件

其他的

  • 獲得進(jìn)程IDgetpid 獲得進(jìn)程IDgetppid

    • 設(shè)置用戶和用戶組

      • 設(shè)置有效用戶ID和實(shí)際用戶ID

        setpid

      • 設(shè)置實(shí)際組和有效組

        setgid

      若進(jìn)程具有root權(quán)限,則函數(shù)將實(shí)際用戶ID有效用戶ID設(shè)置為參數(shù)UID。

      若進(jìn)程沒有root權(quán)限,但UID為實(shí)際用戶,setuid只將有效用戶ID設(shè)為UID。

  • 改變進(jìn)程的優(yōu)先級(jí)。

    nice函數(shù)

    函數(shù) 原型 作用
    nice int nice(int increment) 改變程序的優(yōu)先級(jí)
    getpriority int getpriority(int which, int who) 獲取文件優(yōu)先級(jí)
    setpriority int setpriority(int which, int who, int prio) 設(shè)置文件優(yōu)先級(jí)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Linux 進(jìn)程管理與程序開發(fā) 進(jìn)程是Linux事務(wù)管理的基本單元,所有的進(jìn)程均擁有自己獨(dú)立的處理環(huán)境和系統(tǒng)資源,...
    JamesPeng閱讀 2,589評(píng)論 1 14
  • 進(jìn)程間通信(IPC - InterProcess Communication) 通信的方式有很多: 文件, 管道,...
    wulegekong閱讀 569評(píng)論 0 1
  • ### main函數(shù)執(zhí)行之前做了什么?(iOS) & dyld 是Apple 的動(dòng)態(tài)鏈接器;在 xnu 內(nèi)核為程...
    天使君閱讀 769評(píng)論 0 1
  • 今天是個(gè)好日子。 剛剛接到堂弟電話,平常這個(gè)點(diǎn)很少會(huì)給我打電話,我一拿起電話,猜想估計(jì)是梅梅生了。一接電話,他就急...
    追夢人2016閱讀 127評(píng)論 0 1
  • 多少歲月可以輕描淡寫, 多少情感可以熱情洋溢? 昨天的你我不曾深度愛戀, 老天就玩起了生離死別。
    卡卡不在線閱讀 202評(píng)論 0 0

友情鏈接更多精彩內(nèi)容