進程定義
進程是一個具有一定獨立功能的程序的一次運行活動,同時也是資源分配的最小單元
進程與程序
進程是動態的,程序是靜態的
程序是有序代碼的集合,進程是程序的執行。通常進程不可在計算機之間遷移,而程序同城對應着文件、靜態和可以複製。
進程是暫時的,程序是長久的
進程是一個狀態變化的過程,程序可長久保存。
進程與程序組成不同
進程的組成包括程序、數據和進程控制塊(即進程狀態信息)。
進程與程序的對應關係
通過多次執行,一個程序可對應多個程序,通過調用關係,一個進程可包括多個程序。
進程的生命週期
創建
每個進程都是由其父進程創建,進程可以創建子進程,子進程又可以創建子進程的子進程。
運行
多個進程可以同時存在,進程間可以通信。
撤銷
進程可以被撤銷,從而結束一個進程的運行
pid
每個進程都有他所對應的process id(pid),具體值(系統分配)可以用get()函數獲得
ppid是pid父進程
進程的狀態
執行狀態
進程正在佔用CPU
就緒狀態
進程已具備一切條件,正在等待分配CPU的處理時間片
等待狀態
進程不能使用CPU,若等待事件發生則可將其喚醒
進程互斥
當有若干個進程都要使用某一共享資源時,任何時刻最多允許一個進程使用,其他要使用該資源的進程必須等待,直到佔用該自願者釋放了該資源爲止。
臨界資源
操作系統中將一次只允許一個進程訪問的資源稱爲臨界資源。
應避免出現類似臨界資源情況
進程同步
一組併發進程按一定的順序執行的過程稱爲進程間的同步,具有同步關係一組併發進程稱爲合作進程,合作進程互相發送的信號稱爲消息或事件。
死鎖
多個進程因競爭資源而形成一種僵局,若無外力作用,這些進程將永遠不能再向前推進。
進程創建
pid_t fork(void)
表頭文件 #include
功能:創建子進程
fork的奇妙之處在於它被調用一次,卻返回兩次,它可能有三種不同的返回值。
pid=0表示爲子進程
pid>0表示爲主進程
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(){
int i=0;
pid_t pid=fork();//此時出現分支子進程
if(pid==-1){
perror("fork error!");
exit(1);
}
if(pid==0){//sub process 子進程
for(;i<10;i++){
sleep(1);
printf("child:%d\n",i);
}
}
else if(pid>0){//parent process 主進程
for(;i<10;i++){
sleep(1);
printf("parent:%d\n",i);
}
}
printf("````````%d`````````\n",pid);
}
在pid=fork()之前,只有一個進程在執行,但在這條語句執行之後,就變成了了兩個進程在執行,這兩個進程的共享代碼段,將要執行的下一條語句都是if(pid==0)。
兩個進程中,原來就存在的那個進程被稱作“父進程”,新出現的那個進程被稱作“子進程”,父子進程的區別在於進程標識符(pid)不同。
pid_t vfork(void)
表頭文件 #include <unistd.h>
vfork()就會產生一個新的子進程,其子進程會複製父進程的數據與堆棧空間,並集成父進程的用戶代碼,組代碼,環境變量,已打開的文件代碼,工作目錄和資源限制等。
子進程不會繼承父進程的文件鎖定和未處理的信號。
注意,fork,linux不保證子進程會比父進程先執行或晚執行,因此編寫程序時要留意死鎖或競爭條件的發生。vfok保證子進程先運行,共享內存。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
pid_t pid;
int count=0;
pid=vfork();
if(0==pid)
{
count++;
printf("count=%d\n",count);
exit(1);
}
else if(pid>0)
{
count++;
printf("count=%d\n",count);
}
return 0;
}
exec函數族
exec用被執行的程序替換調用它的程序
區別:fork創建一個新的進程,產生一個新的pid;exec啓動一個新程序,替換原有的進程,因此進程的pid不會改變.
進程等待
#include<sys/types.h>
#include<sys/wait.h>
pid_t waitpid(pid_t,int *status,int options)
會暫時停止目前進程的執行,知道有信號來到或子進程結束。