亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Linux進程等待和進程替換詳解

 更新時間:2024年12月10日 11:40:59   作者:無空念  
本文介紹了Linux系統(tǒng)中進程等待的重要性,包括防止內(nèi)存泄露和獲取子進程狀態(tài),詳細講解了wait()和waitpid()函數(shù)的使用,接著,探討了進程替換的概念,通過exec系列函數(shù)實現(xiàn)程序替換,講解了不同函數(shù)的用法和參數(shù)含義,需要的朋友可以參考下

進程等待

前面我們了解了如果父進程沒有回收子進程, 那么當(dāng)子進程接收后, 就會一直處于僵尸狀態(tài), 導(dǎo)致內(nèi)存泄漏, 那么我們?nèi)绾巫尭高M程來回收子進程的資源.

waitpid

我們可以通過 Linux 提供的系統(tǒng)調(diào)用函數(shù) wait 系列函數(shù)來等待子進程死亡, 并回收資源.

wait函數(shù)用于等待任何一個子進程結(jié)束, 并回收其資源. 

  • status:指向整數(shù)的指針, 用于存儲子進程的退出狀態(tài). 如果不需要這個信息, 可以傳遞NULL.
  • 成功時返回被等待的子進程的PID, 失敗時返回 -1, 并設(shè)置 errno.

waitpid函數(shù)允許父進程等待特定的子進程結(jié)束

  • pid:子進程的PID. 如果為 -1, 則等待任何一個子進程。
  • status:同wait函數(shù).
  • options:等待選項, 常用的有 WNOHANG (非阻塞等待). 
  • 成功時返回被等待的子進程的PID. 失敗時返回-1,并設(shè)置errno。

一般來說, 用 waitpid 多一點, 因為 waitpid 提供的更為細致的操作.

int main()    
{    
    pid_t id = fork();    
    if(id<0)    
    {    
        perror("fork");    
        exit(1);    
    }    
    if(id==0)//子進程代碼    
    {    
        int count = 5;    
        while(count)    
        {    
            printf("[%d]我是子進程,我的pid是: %d\n",count,getpid());    
            sleep(1);    
            count--;    
        }    
        exit(0);//子進程執(zhí)行完代碼后退出, exit 會直接終止本進程                                                                        
    }                                                                                                    
    //父進程代碼                                                                                         
    waitpid(id,NULL,0);                                                                                  
    printf("等待子進程成功!\n");                                                                         
    return 0;     
}

可以觀察到, 在等待子進程結(jié)束之前, 父進程卡在了 waitpid(), 直到子進程都被等待成功, 父進程才會繼續(xù)向后執(zhí)行.

status 參數(shù)

在 wait 和 waitpid 函數(shù)中都存在一個 status 的參數(shù).
在 status 中存儲著子進程的退出碼和退出信號.
如果父進程想要了解子進程的退出信息, 可以通過 status 來了解.

status 是一個 int 類型的變量, 一共有 32 個bit, 我們主要看它的低 16 位bit.

那么如何獲取退出狀態(tài) (退出碼) 和 信號

退出狀態(tài) (退出碼):
(status >> 8) & 0xFF
退出信號:
status & 0x7F
int main()    
{    
    pid_t id = fork();    
    if(id<0)    
    {    
        perror("fork");    
        exit(1);    
    }    
    
    if(id==0)//子進程代碼    
    {    
        int count = 5;    
        while(count)    
        {    
            printf("[%d]我是子進程,我的pid是: %d\n",count,getpid());    
            sleep(1);    
            count--;    
        }    
        exit(55);//子進程執(zhí)行完代碼后退出                                                                                                                               
    }    
    //父進程代碼    
    int status = 0;    
    waitpid(id,&status,0);    
    printf("等待子進程成功!\n");    
    printf("進程退出碼: %d,進程退出信號: %d\n",(status >> 8) & 0xFF,status & 0x7F);    
    return 0;    
}  

當(dāng)子進程在運行時, 使用 kill -9 617714命令, 來終止子進程, 那么也就能觀察到, 退出信號為 9.

option

在前面的參數(shù)解釋中說到, 這是一個等待選項.
父進程可以選擇一直阻塞下去, 直到等到子進程的死亡,
或者當(dāng)子進程還沒死亡時, 父進程去執(zhí)行其他的代碼. 等一會再來查看子進程是否死亡.

waitpid(pid,&status,WNOHANG); // 非阻塞等待
waitpid(pid,&status,0); // 阻塞等待
 
int main()
{
    pid_t id = fork();
    if(id<0)
    {
        perror("fork");
        exit(1);
    }
 
    if(id==0)//子進程代碼
    {
        int count = 5;
        while(count)
        {
            printf("[%d]我是子進程,我的pid是: %d\n",count,getpid());
            sleep(1);
            count--;
        }
        exit(55);//子進程執(zhí)行完代碼后退出
    }
    //父進程代碼
    while(1)//循環(huán)訪問子進程退出情況
    {
        int wait = waitpid(id,NULL,WNOHANG);
        if(wait>0)//子進程退出成功
        {
            printf("子進程退出成功,子進程pid: %d\n",wait);
            break;
        }
        else if(wait==0)//子進程還沒退出,父進程干自己的事情
        {
            //此處簡單模擬父進程干的事情
            printf("我是父進程\n");
        }
        else //等待子進程退出失敗
        {
            perror("waitpid");
            exit(1);
        }
        sleep(1);
    }
    return 0;
}

執(zhí)行上面的代碼就能觀察到, 在子進程結(jié)束前, 父進程還在向頻幕上打印文字.

進程替換

創(chuàng)建子進程是為了完成一些工作, 但是子進程的代碼和父進程是一樣的,
有可能子進程并不需要執(zhí)行父進程的代碼, 而是執(zhí)行一些其他代碼.
這種場景下, 就可以使用進程替換.

我們?yōu)槭裁床恢苯訉⒆舆M程要執(zhí)行的代碼寫在父進程中呢, 還要去使用進程替換?

1. 如果所有的代碼都放在父進程中, 那么父進程的代碼會有多么的龐大,

這會提高代碼編寫和維護的成本. 

2. 進程所執(zhí)行的一定是我們的C/C++程序嗎? 進程也可以執(zhí)行其他的非 C/C++ 程序,

那對于那些非 C/C++ 程序 (java程序), 我們無法將他們和我們所寫的 C/C++ 代碼整合在一起, java 和 C/C++ 的運行環(huán)境都不同.

exec 系列函數(shù)

如果想要創(chuàng)建出來的子進程執(zhí)行全新的程序, 可以使用 exec 系列函數(shù)進行程序替換.

一共有6個函數(shù), 其中主要分為兩類
1. execl 系列
2. execv 系列

execl

int main()    
{    
    printf("進行程序替換了\n");    
    int n = execl("/usr/bin/ls","ls","-a","-l",NULL);                                                                                                                   
    if(n==-1)    
    {    
        perror("execl");    
    }    
    printf("程序替換完畢!\n");    
    return 0;    
}    

execl參數(shù): 第一個是要執(zhí)行程序的路徑 (/usr/bin/ls),
第二個參數(shù)是要執(zhí)行的程序的名稱 (ls),

后面的參數(shù)到 NULL 之前, 都是要替換的程序參數(shù) (-a, -l, 都是 ls 程序的參數(shù)).

execl 中 l, 表示如何將參數(shù)傳遞要替換的程序. l 表示通過一個列表的方式,
即向上面的 "-l", "-a"..., 一個列表的形式.

execlp 和 execle 兩個函數(shù)則分別多了 p 和 e.

p 則代表要執(zhí)行的程序可以從環(huán)境變量 PATH 中找到, 所以不用寫執(zhí)行程序的路徑.

e 則表示, 可以傳入用戶自己定義的環(huán)境變量 (_env[]) 給程序使用.

int main()    
{    
    printf("我要進行程序替換了...\n");    
    int n = execlp("ls","-l",NULL);                                                                                                                                     
    if(n==-1)    
    {    
        perror("execl");    
    }    
    printf("程序替換完畢!\n");    
    return 0;    
} 
 
int main()    
{    
    const char* _env[]={"MY_ENV=666",NULL};    
    printf("我要進行程序替換了...\n");    
    int n = execle("/usr/bin/ls","ls","-l",NULL,_env);//自己定義一個環(huán)境變量MY_ENV=666傳遞給要去執(zhí)行的程序                                                              
    if(n==-1)    
    {    
        perror("execl");    
    }    
    printf("程序替換完畢!\n");    
    return 0;    
}  

execv 

上面的 execl 中的 l, 代表傳參使用列表的形式.
那么 v 很容易就想到了是vector.
所以 execv 函數(shù)在給替換的程序傳參時, 是通過一個 vector 來傳參的.

int main()    
  {    
	  char* const set[]={"ls","-a","-l",NULL};  
      printf("我要進行程序替換了...\n");    
      int n = execv("/usr/bin/ls",set);                                                                             
      if(n==-1)    
      {    
          perror("execl");    
      }    
      printf("程序替換完畢!\n");    
      return 0;    
  } 

那么剩下的 execvp 和 execvpe 和之前的 execl 系列中的一樣.
p 代表在環(huán)境變量 PATH 中查找, e 可以傳入自己定義的環(huán)境變量.

  • l (list): 傳參的方式為使用列表來傳遞
  • v (vector): 使用數(shù)組來傳遞參數(shù)
  • p (path): 會在環(huán)境變量 PATH 中查找程序
  • e (env): 可以傳遞自己定義的環(huán)境變量

以上就是Linux進程等待和進程替換詳解的詳細內(nèi)容,更多關(guān)于Linux進程等待和替換的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • centos7下NFS使用與配置的步驟

    centos7下NFS使用與配置的步驟

    本篇文章主要介紹了centos7下NFS使用與配置的步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Apache Pulsar 微信大流量實時推薦場景下實踐詳解

    Apache Pulsar 微信大流量實時推薦場景下實踐詳解

    這篇文章主要為大家介紹了Apache Pulsar 微信大流量實時推薦場景下實踐詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Linux云服務(wù)器掛載新磁盤的方法步驟

    Linux云服務(wù)器掛載新磁盤的方法步驟

    這篇文章主要介紹了Linux云服務(wù)器掛載新磁盤的方法步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-06-06
  • Linux上虛擬機顯示網(wǎng)絡(luò)不可用的解決方法

    Linux上虛擬機顯示網(wǎng)絡(luò)不可用的解決方法

    這篇文章主要介紹了Linux上虛擬機顯示網(wǎng)絡(luò)不可用的解決方法,文中通過圖文結(jié)合的方式講解的非常詳細,對大家解決問題有一定的幫助,需要的朋友可以參考下
    2024-12-12
  • Ubuntu18.04一次性升級Python所有庫的方法步驟

    Ubuntu18.04一次性升級Python所有庫的方法步驟

    這篇文章主要介紹了Ubuntu18.04一次性升級Python所有庫的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • 通過案例深入解析linux NFS機制

    通過案例深入解析linux NFS機制

    這篇文章主要介紹了通過案例深入解析linux NFS機制,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • CentOS 安裝 Mongodb詳解(在線和離線)

    CentOS 安裝 Mongodb詳解(在線和離線)

    這篇文章主要介紹了CentOS 安裝 Mogodb詳解(在線和離線) ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • Linux中FTP服務(wù)器搭建與安全配置方式

    Linux中FTP服務(wù)器搭建與安全配置方式

    這篇文章主要介紹了Linux中FTP服務(wù)器搭建與安全配置方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • Linux下如何安裝與設(shè)置Vim編輯器

    Linux下如何安裝與設(shè)置Vim編輯器

    CentOS7.4系統(tǒng)默認安裝了Vi編輯器,但未完全安裝Vim,本文介紹如何通過yum命令完整安裝Vim所需的四個包,并提供兩種編輯環(huán)境設(shè)置方式
    2024-11-11
  • Linux防火墻iptables添加白名單方式

    Linux防火墻iptables添加白名單方式

    這篇文章主要介紹了Linux防火墻iptables添加白名單方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06

最新評論