應用開發第三天程序控制(國嵌筆記)
1.程序是一個具有一定獨立功能的程式的一次執行活動
程序和程式的區別:程式在執行時就是程序了。程式是靜態的(在磁碟上儲存著),
特點:動態性,併發性,獨立性,非同步性
狀態轉換圖:三態
就緒,阻塞,執行
程序互斥:
當有若干程序都需要使用某一共享資源時,任何時刻最多允許一個程序使用,其他要使用該資源的程序必須等待,直到佔用該資源者釋放了該資源為止。
臨界資源:
作業系統中將一次值允許一個程序訪問的資源稱為臨界資源
臨界區:
程序中訪問臨界資源的那段程式程式碼稱為臨界區。為實現對臨界資源的互斥訪問,應保證諸程序互斥地進入各自的臨界區
程序同步:
一組併發程序按一定的順序執行的過程稱為程序間的同步。具有同步關係的一組併發程序稱為合作程序。合作程序間相互發送的訊號稱為訊息或事件
程序排程:
按照一定演算法,從一組待執行的程序中選出一個來佔有CPU執行。
排程方式:
搶佔式,非搶佔式
排程演算法:
先來先服務排程演算法
短程序優先排程演算法
高優先順序優先排程演算法
時間片輪轉法
死鎖:
多個程序因競爭資源而形成一種僵局,若無外力作用,這些程序都將永遠不能再向前推進
2.程序控制程式設計
1.獲取ID
#include<sys/types.h>
#include<unistd.h>
pid_t getpid(void); //獲取本程序ID
pid_t getppid(void); //獲取父程序ID
2.建立程序
1.fork
#include<unistd.h>
pid_t fork(void);//建立子程序
被呼叫一次卻返回兩次:
1.父程序中,返回子程序的PID
2.子程序中返回0
3.出現錯誤返回一個負值
會將fork之後的程式碼複製(此處複製非實際複製而是一個抽象意義上的複製->共享)一份開始執行,就是fork之後有兩段相同的程式碼(程式碼段)執行。fork之後的程式碼子程序執行一次,父程序執行一次。但是是共享的程式碼段的程式碼
資料部分(資料段、棧等)拷貝一份。資料獨立,程式碼共享
2.vfork
#include <sys/typrs.h>
#include <unistd.h>
pid_t vfork(void); //建立子程序
fork PK vfork
1.fork:子程序拷貝父程序的資料段
vfork:子程序共享父程序的資料段
2.fork:父子程序的執行次序不確定
vfork:子程序先執行,父程序後執行
vfork子程序執行完後才執行父程序。vfork函式產生的父子程序必定是子程序先執行完,父程序才會開始執行
3.exec函式族
1.exec用被執行的程式替換呼叫它的程式(不會產生新的程序)
區別:
fork建立一個新的程序,產生一個新的PID
exec啟動一個新程式,替換原有的程序,因此程序的PID不會改變
2.常見的exec函式
1.execl(path,arg1,...); path 被執行程式名(含有完整路徑),arg1-argn 被執行程式所需的命令列引數,含程式名,以空指標(NULL)結束
eg:execl("/bin/ls","ls","-al","/etc/passwd",(char *)0);
2.execlp(path,arg1-argn); path被執行的程式名(不含路徑,將從path環境變數中查詢該程式),arg1-argn 同上
`3.execv(path argv[]);path 被執行的程式(含完整路徑),argv被執行程式所需的命令列引數陣列
4.int system(const char* string)
呼叫fork產生子程序,由子程序來呼叫/bin/sh -c string 來執行引數string所代表的命令
eg:system("ls -al /etc/passed");
exec函式族會在一個程序中啟動另一個程式執行。並用他來取代呼叫程序的資料段、程式碼段、和錐棧段。在執行完exec函式呼叫後,原呼叫程序的內容除了程序號外,其他全部被新的程序替換了。
4.程序等待
#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int* status);
阻塞該程序,直到其中某個子程序退出
waitpid()
//使父程序阻塞,等待子程序退出,來確保子程序先結束。
if(pc==0)
{···}
else{
pr=wait(NULL);
···
}
都是子程序先執行父程序再執行