進程創(chuàng)建
創(chuàng)建進程:
pid_t fork(void);
返回值:
失敗 -1, 成功返回兩次糊啡,在父進程中返回值為子進程ID栋荸,在子進程中返回父進程ID
注:
子進程的代碼和父進程的代碼是一致的,但是子進程啟動之后是從fork之后開始執(zhí)行的
獲得pid跟畅,進程id咽筋,獲得當前進程:
pid_t fork(void);
獲得當前進程父進程的id
pid_t getppid(void);
進程創(chuàng)建示例代碼:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
printf("Begin ....\n");
pid_t pid = fork();
if(pid < 0){
perror("fork err");
exit(1);
}
if(pid == 0){
//子進程
printf("I am a child,pid = %d,ppid=%d\n",getpid(),getppid());
while(1){
printf("I am a child\n");
sleep(1);
}
}
else if(pid > 0){
//父進程的邏輯
printf("childpid=%d,self=%d,ppid=%d\n",pid,getpid(),getppid());
while(1){
sleep(1);
}
}
printf("End ....\n");
return 0;
}
代碼示例 用父進程創(chuàng)建N個子進程:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
int n = 5;
int i =0;
pid_t pid = 0;
for(i = 0; i < 5 ; i ++){//父進程循環(huán)結束
pid = fork();
if(pid == 0){
//son
printf("I am child ,pid=%d,ppid=%d\n",getpid(),getppid());
break;//子進程退出循環(huán)的接口 , 否則子進程也會創(chuàng)建自己的子進程,因為fork是在一個循環(huán)中的
}else if(pid > 0){
//father
printf("I am father,pid=%d,ppid=%d\n",getpid(),getppid());
}
}
sleep(i);
if(i < 5){
printf("I am child ,will exit,pid=%d,ppid=%d\n",getpid(),getppid());
}
else{
//father
printf("I am parent,will out pid=%d,ppid=%d\n",getpid(),getppid());
}
return 0;
}
進程共享
父子進程之間在fork后碍彭。有哪些相同晤硕,哪些相異之處呢?
fork之后:
父子進程相同之處:全局變量庇忌、.data(數(shù)據(jù)塊)舞箍、.text(代碼塊)、棧皆疹、堆疏橄、環(huán)境變量、用戶ID略就、宿主目錄捎迫、進程工作目錄,信號處理方...
父子進程不同之處:進程ID表牢、fork返回值窄绒、父進程ID、進程運行時間崔兴、鬧鐘彰导、未解決信號集
那么子進程復制了父進程的用戶空間內(nèi)容,已經(jīng)父進程的PCB敲茄,但pid不同位谋。子進程每fork一次都要將父進程的地址空間完全拷貝一份,然后映射至物理內(nèi)存嗎堰燎?
答案是不是的掏父。父子進程間遵循讀時共享寫時復制的原則,這樣設計秆剪,無論子進程執(zhí)行父進程的邏輯還是執(zhí)行自己的邏輯都能節(jié)省內(nèi)存開銷赊淑。
關于全局變量,子進程雖然是也擁有同樣的全局變量仅讽,但是父子進程的內(nèi)存是獨立的膏燃,所以不會有競爭問題
代碼示例 父子進程不共享全局變量:
#include <stdio.h>
#include <unistd.h>
int var = 100;
int main()
{
pid_t pid = fork();
if(pid == 0){
//son
var = 1001;
printf("address = %d var = %d,child,pid=%d,ppid=%d\n",&var,var,getpid(),getppid());
sleep(3);
printf("address = %d var = %d,child,pid=%d,ppid=%d\n",&var,var,getpid(),getppid());
}
else if(pid > 0){
//parent
sleep(1);//保障子進程能夠修改var的值成功
printf("address = %d var = %d,parent,pid=%d,ppid=%d\n",&var,var,getpid(),getppid());
var=2000;
printf("address = %d var = %d,parent,pid=%d,ppid=%d\n",&var,var,getpid(),getppid());
}
return 0;
}