欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言控制進(jìn)程之進(jìn)程等待詳解

 更新時間:2022年08月29日 09:35:56   作者:小小酥誒  
這篇文章主要介紹了C語言控制進(jìn)程之進(jìn)程等待即回收子進(jìn)程的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

進(jìn)程等待的必要

當(dāng)一個進(jìn)程終止的時候,它的資源,比如說PCB,數(shù)據(jù)等不會被立馬清理掉。它會保持在已經(jīng)終止的狀態(tài),這種狀態(tài)稱為“僵尸狀態(tài)”,直到被父進(jìn)程確認(rèn)。父進(jìn)程wait,即父進(jìn)程向內(nèi)核確認(rèn)子進(jìn)程已經(jīng)終止,可以為子進(jìn)程“收尸”了,內(nèi)核會把子進(jìn)程的退出信息傳給父進(jìn)程,然后清理掉子進(jìn)程的資源,這個時候子進(jìn)程才算真正地終止了!

總結(jié):

  • 父進(jìn)程等待,可以獲取子進(jìn)程的退出信息,知道子進(jìn)程的執(zhí)行結(jié)果。
  • 父進(jìn)程等待,可以釋放子進(jìn)程的資源,讓子進(jìn)程真正地退出,避免一直消耗系統(tǒng)的存儲資源,造成“內(nèi)存泄露”等危害。
  • 父進(jìn)程等待,可以保證時序的問題,子進(jìn)程先于父進(jìn)程退出,避免讓子進(jìn)程變?yōu)楣聝哼M(jìn)程。

進(jìn)程等待的方法

wait函數(shù)

一個進(jìn)程可以通過調(diào)用wait函數(shù)等待子進(jìn)程。wait函數(shù)是系統(tǒng)調(diào)用函數(shù)。

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

返回值:返回被等待進(jìn)程的pid,如果等待失敗,返回-1。

參數(shù):輸出型參數(shù),可以獲取子進(jìn)程的退出狀態(tài),如果不需要獲取子進(jìn)程的退出狀態(tài),則設(shè)置為NULL。

測試:

 #include <stdio.h>                                                     
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <stdlib.h>
 int main(void)
 {
   pid_t id = fork(); //創(chuàng)建子進(jìn)程
   if(id == 0)
   {
     //child
     //執(zhí)行5秒
     int cnt = 5;
     while(cnt)
     {
       printf("child[%d] , cnt:%d\n", getpid(), cnt);
       sleep(1);
       cnt--;
     }
     exit(EXIT_SUCCESS);
   }
   sleep(10);
   pid_t ret = wait(NULL);
   if(ret > 0)
   {
     //wait success, ret is pid;
     printf("father wait child[%d] success\n", ret);
   }
   else{                                                                
     //wait failed.
     printf("father wait failed\n");
   }
   return 0;
 }

現(xiàn)象:子進(jìn)程執(zhí)行5秒后,終止了,但是內(nèi)核沒有立馬清理掉它的資源,所以此時是僵尸狀態(tài),再過了5秒之后,父進(jìn)程休眠完畢,然后等待子進(jìn)程,確認(rèn)子進(jìn)程已經(jīng)終止,返回子進(jìn)程的pid,然后內(nèi)核開始清理子進(jìn)程資源,子進(jìn)程真正地終止了,又過了5秒后父進(jìn)程也終止了。

通過wait函數(shù)的輸出型參數(shù)可以獲得子進(jìn)程的退出信息。

waitpid函數(shù)

waitpid函數(shù)也可以使得父進(jìn)程等待子進(jìn)程

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

先不關(guān)心第二個和第三個參數(shù),第二個參數(shù)可以設(shè)置為NULL,第三個參數(shù)暫時設(shè)置為0。

第一個參數(shù):

1、如果第一個參數(shù)pid傳的是某個具體的進(jìn)程的進(jìn)程ID,表示等待該指定進(jìn)程

2、如果第一個參數(shù)pid傳的是-1,表示等待父進(jìn)程的任意子進(jìn)程。

第三個參數(shù):

  • 傳的是0,表示父進(jìn)程是掛起等待子進(jìn)程的(阻塞等待)??梢岳斫鉃?ldquo;父進(jìn)程在等待子進(jìn)程的過程中,什么事情也沒做,在干等”。
  • 傳的是宏WNOHANG,表示父進(jìn)程是非阻塞等待。若等待的子進(jìn)程還沒有終止,那么waitpid函數(shù)立即返回0,不予以等待。若等待的子進(jìn)程已經(jīng)正常結(jié)束,那么waitpid函數(shù)返回等待子進(jìn)程的PID

wait(&status) 等價于 waitpid(-1, &status, 0)

【注意事項】

  • 如果子進(jìn)程已經(jīng)退出,調(diào)用wait/waitpid時,wait/waitpid會立即返回,獲得子進(jìn)程退出信息,并且釋放被等待子進(jìn)程資源。
  • 如果在任意時刻調(diào)用wait/waitpid,子進(jìn)程存在且還在正常運行,則父進(jìn)程可能會發(fā)生阻塞。
  • 如果試圖等待一個當(dāng)前不存在的進(jìn)程,wait/waitpid會調(diào)用出錯,并立即返回。

獲取子進(jìn)程退出信息

在上述并沒有具體解釋參數(shù)status的作用。

  • 在wait和waitpid函數(shù)中,status的作用是一樣的,它是輸出型參數(shù)。
  • 如果給status傳的是NULL,則表示不需要獲取子進(jìn)程的退出信息。
  • 如果給status傳的是非NULL,則可以獲取被等待進(jìn)程的退出信息。

status是一個指向整形的指針。但是一個進(jìn)程的退出信息那么多,怎么可能會那么簡單地用一個整型就知道進(jìn)程的退出信息了呢?實際上,并不是簡單地看待status指向的整形,而是當(dāng)作位圖來看,一個整型有32位,這樣就可以全面地描述被等待進(jìn)程的退出信息了。

只用研究低16個比特位。

進(jìn)程退出的情況有四種:

1、正常退出(自愿,代碼執(zhí)行完,結(jié)果正確)

2、錯誤退出(自愿,代碼執(zhí)行完,結(jié)果不正確)

3、異常退出(非自愿,代碼未執(zhí)行完,退出碼無意義)

4、被其他進(jìn)程終止(非自愿,代碼未執(zhí)行完,退出碼無意義)

這四種情況,可以按照進(jìn)程是否收到信號來分類,第一種和第二種進(jìn)程未收到信號,第三和第四種進(jìn)程收到信號。

當(dāng)被等待進(jìn)程不是被信號所終止時,低8位全是0,而次低8位則是被等待進(jìn)程的退出碼。

當(dāng)被等待進(jìn)程是被信號所終止時,低7位表示被等待進(jìn)程收到的信號。

如果進(jìn)程是正常終止,如何顯示地知道退出碼?

如果進(jìn)程是收到信號而終止,如何知道它收到了什么信號?直接就是低7位表示的是進(jìn)程收到的信號,如果是非法的信號,說明它沒有收到信號,這個值是無效的。

測試:

 #include <stdio.h>                                                    
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <stdlib.h>
 
 int main(void)
 {
   pid_t id = fork(); //創(chuàng)建子進(jìn)程
   if(id == 0)
   {
     //child
     //執(zhí)行5秒
     int cnt =7;
     while(cnt)
     {
       printf("child[%d] , cnt:%d\n", getpid(), cnt);
       sleep(1);
       cnt--;
     }
     exit(12);
   }
   sleep(10);
   int status;
   pid_t ret = waitpid(id, &status, 0);
   if(ret > 0)
   {
     //wait success, ret is pid;
     printf("father wait child[%d] success\n", ret);
   }
   else{
     //wait failed.
   printf("father wait failed\n");
   }
   printf("get a exit num : %d\n, get a single:%d", (status >> 8) & 0XF    FFF, status & 0XFFFF);
   sleep(2);                                                           
   return 0;
 }

當(dāng)然,還可以不需要進(jìn)行位運算,系統(tǒng)提供了兩個宏,可以得到退出信息

  • WIFEXITED(status):如果被等待進(jìn)程正常退出則未真。
  • WEXITSTATUS(status):如果WFIEXITED(status)為真,提取被等待進(jìn)程的退出碼。
 #include <stdio.h>                                                                                                                                              
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <stdlib.h>
 int main(void)
 {
   pid_t id = fork(); //創(chuàng)建子進(jìn)程
   if(id == 0)
   {
     //child
    //執(zhí)行5秒
    printf("i am child precess\n");
    sleep(5);
    exit(12);
  }
  sleep(3);
  int status;
  printf("father begin wait\n");
  pid_t ret = waitpid(id, &status, 0);
  if(ret > 0)
 {
    //wait success, ret is pid;
    printf("father wait child[%d] success\n", ret);
  }
  else{
    //wait failed.
    printf("father wait failed\n");
  }
  if(WIFEXITED(status))
  {
    printf("exit code : %d\n", WEXITSTATUS(status));
  }
  else{
    printf("get a signal\n");
 }
  sleep(2);
  return 0;
}   

執(zhí)行結(jié)果

到此這篇關(guān)于C語言控制進(jìn)程之進(jìn)程等待詳解的文章就介紹到這了,更多相關(guān)C語言進(jìn)程等待內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++?STL容器適配器使用指南

    C++?STL容器適配器使用指南

    C++?STL(標(biāo)準(zhǔn)模板庫)是一套功能強大的?C++?模板類,提供了通用的模板類和函數(shù),這些模板類和函數(shù)可以實現(xiàn)多種流行和常用的算法和數(shù)據(jù)結(jié)構(gòu),如向量、鏈表、隊列、棧,今天我們來探究一下stl容器適配器的使用吧
    2021-11-11
  • C/C++ 中堆和棧及靜態(tài)數(shù)據(jù)區(qū)詳解

    C/C++ 中堆和棧及靜態(tài)數(shù)據(jù)區(qū)詳解

    這篇文章主要介紹了C/C++ 中堆和棧及靜態(tài)數(shù)據(jù)區(qū)詳解的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • C++用Dijkstra(迪杰斯特拉)算法求最短路徑

    C++用Dijkstra(迪杰斯特拉)算法求最短路徑

    Dijkstra(迪杰斯特拉)算法是典型的最短路徑路由算法,用于計算一個節(jié)點到其他所有節(jié)點的最短路徑。主要特點是以起始點為中心向外層層擴展,直到擴展到終點為止。下面這篇文章就給大家介紹關(guān)于C++用Dijkstra算法(迪杰斯特拉算法)求最短路徑的方法,下面來一起看看吧。
    2016-12-12
  • C++實現(xiàn)簡易文本編輯器

    C++實現(xiàn)簡易文本編輯器

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)簡易文本編輯器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • 解析C++中派生的概念以及派生類成員的訪問屬性

    解析C++中派生的概念以及派生類成員的訪問屬性

    這篇文章主要介紹了解析C++中派生的概念以及派生類成員的訪問屬性,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • c++隱式類型轉(zhuǎn)換存在的問題解析

    c++隱式類型轉(zhuǎn)換存在的問題解析

    隱式轉(zhuǎn)換,是指不需要用戶干預(yù),編譯器私下進(jìn)行的類型轉(zhuǎn)換行為,很多時候用戶都不知道具體進(jìn)行了哪些轉(zhuǎn)換,這篇文章主要介紹了c++隱式類型轉(zhuǎn)換存在的陷阱,需要的朋友可以參考下
    2022-03-03
  • C++ 字符串string和整數(shù)int的互相轉(zhuǎn)化操作

    C++ 字符串string和整數(shù)int的互相轉(zhuǎn)化操作

    這篇文章主要介紹了C++ 字符串string和整數(shù)int的互相轉(zhuǎn)化操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 在iOS中給視頻添加濾鏡的方法示例

    在iOS中給視頻添加濾鏡的方法示例

    這篇文章主要介紹了在iOS中給視頻添加濾鏡的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • 最新評論