1. 程式人生 > >[Linux C程式設計]程序控制

[Linux C程式設計]程序控制

程序控制

1.什麼是程序?

程序是一個具有一定獨立功能的程式的一次執行活動,同時也是資源分配的最小單元

2.程序與程式的區別?

·程式是放到磁碟的可執行檔案程序是指程式執行的例項

·程序是動態的,程式是靜態的:程式是有序程式碼的集合;程序是程式的執行。通常程序不可在計算機之間遷

 移;而程式通常對應著檔案、靜態和可以複製。

·程序是暫時的,程式是長久的:程序是一個狀態變化的過程,程式可長久儲存。

·程序與程式的組成不同:程序的組成包括程式、資料和程序控制塊(即程序狀態資訊)

·程序與程式的對應關係:通過多次執行,一個程式可對應多個程序;通過呼叫關係,一個

程序可包括多個程式。

3.程序的生命週期?

建立:每個程序都是由其父程序建立程序可以建立子程序,子程序又可以建立子程序的子程序

執行:多個程序可以同時存在程序間可以通訊

撤銷:程序可以被撤銷,從而結束一個程式的執行。

4.程序的狀態?

執行狀態:程序正在佔用CPU

就緒狀態:程序已具備一切條件,正在等待分配CPU的處理時間片

等待狀態:程序不能使用CPU,若等待時間發生則可將其喚醒

 

5.Linux下程序地址空間?

Linux中的程序包含3個段,分別為:資料段、程式碼段、堆疊段

資料段:存放全域性變數,常數、以及動態資料分配的資料空間

程式碼段:存放程式程式碼的資料

堆疊段:存放的是子程式的返回地址、子程式的引數以及程式的區域性變數等。

 

6.什麼是程序互斥?

程序互斥是指當有若干程序都要使用某一共享資源時,任何時刻最多允許一個程序使用,其他要使用該資源的程序必須等待,直到佔用該資源者釋放了該資源為止。

7.什麼是臨界資源?

作業系統中將一次只允許一個程序訪問的資源稱為臨界資源。

程序中訪問臨界資源的那段程式程式碼稱為臨界區,為實現對臨界資源的互斥訪問,應保證諸程序互斥地進入各自的臨界區。

8.什麼是程序同步?

一組併發程序按一定順序執行的過程稱為程序間的同步,具有同步關係的一組併發程序稱為合作程序,合作程序間互相傳送的訊號稱為訊息或事件。

9.程序的排程演算法有哪些?什麼是優先順序反轉?

概念:按一定演算法,從一組待執行的程序中選出一個來佔有CPU執行

排程方式:搶佔式、非搶佔式

排程演算法:先來先服務排程演算法

     短程序優先排程演算法

      高優先順序優先排程演算法

     時間片輪轉法

所謂優先順序翻轉問題(priority inversion)即當一個高優先順序任務通過訊號量機制訪問共享資源時,該訊號量已被一低優先順序任務佔有,而這個低優先順序任務在訪問共享資源時可能又被其它一些中等優先順序任務搶先,因此造成高優先順序任務被許多具有較低優先順序任務阻塞,實時性難以得到保證。

10.什麼是程序死鎖?

多個程序因競爭資源而形成一種僵局,若無外力作用,這些程序將永遠不能再向前推進。

11.程序獲取ID函式

(1)getpid

函式的作用:獲取程序識別碼,程序號

函式的原型:pid_t  getpid(void);

返回值:目前程序的程序號;

標頭檔案: #include  <unistd.h>

12.程序建立函式

(1)fork

函式的作用:建立一個程序

函式的原型:pid_t  fork(void);

函式的返回值:<0   出錯;

         =0   表示當前建立的子程序

         >0   父程序  ,返回值是子程序的程序號

性質:

fork建立的子程序把父程序的資源拷貝了一份,父子程序把所有的重新執行一遍;

vfork建立的子程序和父程序共享資料空間, 不是重新拷貝

(2) vfork

函式的作用:建立一個新的程序;

函式的原型: pid_t vfork();

函式說明:vfork()會產生一個新的子程序,其子程序會複製父程序的資料與堆疊空間,並繼承父程序的使用者程式碼,組程式碼,環境變數,已開啟的檔案程式碼,工作目錄和資源限制等。

子程序不會繼承父程序的檔案鎖定和未處理的訊號。

特點:子程序先執行,退出,父程序才能執行

補:fork()和vfork()區別:

1.fork:子程序拷貝父程序的資料段

 vfork:子程序與父程序共享資料段

2.fork:父、子程序的執行次序不確定

 vfork:子程式先執行、父程序後執行

13.exec函式族

(1)execl

函式的作用: 執行一個檔案,

函式原型: int execl(const char *path, const char *arg,..)

引數說明: path:代表的檔案路徑;

      arg:表示argv[0], argv[1],...

       最後一個以NULL結束;

返回值:成功函式沒有返回,出錯-1;

(2)execv

函式的作用:

函式原型:int exev(const char *path, char * const argv[])

函式的引數: path:代表的檔案路徑;

         argv:是一個數組裡的指標傳遞過來;        

返回值: 成功不返還,出錯-1

(3)system

函式的作用:執行一個命令

函式的原型: int system(const char * string);

14.程序等待函式

(1) wait

函式的作用: 程序的等待,阻塞程序,等待某個子程序退出;

函式的原型: pid_t wait(int *status);

返回值:成功返回子程序PID,出錯-1;

(2) waitpid

函式的作用:會暫時停止目前程序的執行,知道有訊號來到或子程序結束

函式的原型:pid_t  waitpid(pid_t pid , int *status, int options);

函式的引數:

  pid < -1:等待程序的Pid絕對值的任何的子程序;

  pid = -1: 任何子程序,---等於wait;

  pid = 0:等待程序組識別碼與目前程序相同的任何子程序

  pid > 0: 等待子程序為pid的子程序退出

  options:

    WNOHANG:如果沒有子程序退出,馬上返回不等待

     WUNTRACED:如果子程序進入暫停執行情況,馬上返回,

返回值:如果執行成功返回的是子程序的PID,失敗-1;

    如果使用WNOHANG的時候,沒有子程序退出,

15.程序退出函式

(1)exit  

函式的作用:正常結束程序

函式原型: void  exit(int status)

(2)_exit

函式作用:立即結束目前程序的執行

函式原型:void _exit(int status);

exit _exit用於終止程序

區別:_exit:直接使程序停止,清除其使用的記憶體,並清除緩衝區中內容

    exit:在停止程序之前,要檢查檔案的開啟情況,並把檔案緩衝區的內容寫回到檔案

才停止程序。

 

16.什麼是殭屍程序?殭屍程序是如何產生的?如何避免殭屍程序?

殭屍程序指的是那些雖然已經終止的程序,但仍然保留一些資訊,等待其父程序為其收屍。

如果一個程序在其終止的時候,自己就回收所有分配給它的資源,系統就不會產生所謂的殭屍程序了。

殭屍程序產生過程:

1. 父程序呼叫fork建立子程序後,子程序執行直至其終止,它立即從記憶體中移除,但程序描述符仍然保留在記憶體中(程序描述符佔有極少的記憶體空間)。

2. 子程序的狀態變成EXIT_ZOMBIE,並且向父程序傳送SIGCHLD 訊號,父程序此時應該呼叫 wait() 系統呼叫來獲取子程序的退出狀態以及其它的資訊。在 wait 呼叫之後,殭屍程序就完全從記憶體中移除。

3. 因此一個殭屍存在於其終止到父程序呼叫 wait 等函式這個時間的間隙,一般很快就消失,但如果程式設計不合理,父程序從不呼叫 wait 等系統呼叫來收集殭屍程序,那麼這些程序會一直存在記憶體中。