Linux進程

進程的控制

什么是進程

狹義上來說進程是操作系統上運行的一個程序。

廣義上來說進程是一個具有一定獨立功能的程序關于某個數據集合的一次運行活動。它是操作系統動態執行的基本單元,在傳統的操作系統中,進程既是基本的分配單元,也是基本的執行單元。

進程控制是進程管理中最基本的功能。它用于創建一個新進程,終止一個已完成的進程,或者去終止一個因出現某事件而使其無法運行下去的進程,還可負責進程運行中的狀態轉換。

Linux系統上進程的幾種狀態:

  • 運行狀態:進程正在運行,或者在運行隊列中等待運行。
  • 可中斷等待狀態:進程在等待某個事件的完成,在等待中不可以被信號或定時器喚醒,必須等待直到等待的事情發生。
  • 僵死狀態:進程已經終止,但是進程的描述符還在,直到父進程的wait函數釋放。
  • 停止狀態:進程收到系統發出的信號(SIGSTOP SIFTOP SIGTIN SIGTOU )之后停止運行或者該進程正在被跟蹤(調試應用程序gdb,進程處于跟蹤狀態)。

進程的創建

進程的創建一是操作系統來創建。二是由父進程創建。

  • 使用fork函數來分配一個新的進程。

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

創建守護進程

什么是守護進程?這是一段來自維基百科的描述。

  • 在一個多任務的電腦操作系統中,守護進程(英語:daemon)是一種在后臺執行的電腦程序。此類程序會被以進程的形式初始化。守護進程程序的名稱通常以字母“d”結尾:例如,syslogd就是指管理系統日志的守護進程。

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

    系統通常在啟動時一同起動守護進程。守護進程為對網絡請求,硬件活動等進行響應,或其他通過某些任務對其他應用程序的請求進行回應提供支持。守護進程也能夠對硬件進行配置(如在某些Linux系統上的devfsd),運行計劃任務(例如cron),以及運行其他任務。

  • Linux創建一個守護進程創建

孤兒進程與僵尸進程

  • 當父進程先于子進程退出時,子進程會被init或這systemd接收為子進程。這一過程亦被稱為收養,雖然有PID為1的系統進程當做父進程,但是創建他的父進程已經被系統回收了。

    Ubuntu 18.04 LTS的環境下時,收養的父進程為圖形界面的進程。只有進入字符界面運行時,對應收養的父進程才為1

  • 創建孤兒進程與孤兒進程

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

wait 和 waitpid

  • waitwaitpid

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

進程的退出

正常退出 異常退出
調用函數exit\_exit 調用about函數或者由系統發出signal退出。

exit()與_ecit()的區別

函數 區別
exit() 調用該函數后,系統會先執行一些清除操作,然后返還給內核。
_exit() 調用該函數后,馬上拋給內核。

exit與return的區別

區別 操作
exit exit用于結束一個程序
return return用于函數,返回后回到調用的上一層函數

exit的參數,正常退出參數為0,異常退出參數為非零值。

執行新的程序

  • 父進程fork一個子進程后,使用exec函數來調用另外的可執行程序代替當前進程的可執行映像。

    進程一旦調用exec函數后,相當于將原有的進程殺死,只保留進程ID,對于系統而言,同樣的進程,執行的操作不一樣了。

  • exec函數家族

    **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[]);

  • 例子:

    被調用的文件

    調用的文件

其他的

  • 獲得進程IDgetpid 獲得進程IDgetppid

    • 設置用戶和用戶組

      • 設置有效用戶ID和實際用戶ID

        setpid

      • 設置實際組和有效組

        setgid

      若進程具有root權限,則函數將實際用戶ID有效用戶ID設置為參數UID。

      若進程沒有root權限,但UID為實際用戶,setuid只將有效用戶ID設為UID。

  • 改變進程的優先級。

    nice函數

    函數 原型 作用
    nice int nice(int increment) 改變程序的優先級
    getpriority int getpriority(int which, int who) 獲取文件優先級
    setpriority int setpriority(int which, int who, int prio) 設置文件優先級
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評論 6 540
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,275評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 177,904評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,368評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,736評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,919評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,481評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,235評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,427評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,656評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,160評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,380評論 2 379

推薦閱讀更多精彩內容