函数介绍
pid_t fork(void) 复制当前进程,返回值类型为pit_t(相当于int类型)表示进行的pid,在父进程中返回值为子进程的pid 其大于0,在子进程中,其返回值为0,若返回值小于0 表示创建子进程失败。
分析:创建子进程相当于复制了父进程的pcb,pcb在计算机中类似于链表一样串接在一起,所以父进程中返回的pid指向子进程,而子进程返回的pid为0,类似于指向NULL。
创建失败的原因:
- 当前进程数达到上限
- 系统内存不足
注意:子进程虽然有和父进程一样的pcb,但是每个进程的pid都是不一样的,子进程的pid一般 =父进程的pid +1 ,另外父子进程代码相同,数据独享
例:
下面两段代码输出结果相同
int main()
{
int ret = fork();
//父进程中getpid()为父进程pid ,父进程中ret返回值为子进程pid
//子进程中getpid()为子进程pid,子进程中ret返回值为 0
printf("hello proc : %d!, ret: %d\n", getpid(), ret);
sleep(1);
return 0;
}
int main()
{
int ret = fork();
if(ret < 0){
perror("fork");
return 1;
}
else if(ret == 0){ //child
printf("I am child : %d!, ret: %d\n", getpid(), ret);
}else{ //father
printf("I am father : %d!, ret: %d\n", getpid(), ret);
}
sleep(1);
return 0;
}
父子进程代码相同,数据独享
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <unistd.h>
4 int main()
5 {
6 int ret = fork();
7 int count = 100;
8 if(ret < 0){
9 perror("fork");
10 return 1;
11 }
12 else if(ret == 0){ //child
13 printf("I am child : %d!, ret: %d\n", getpid(), ret);
14 count = 20;
15 printf("count = %d\n",count);
16 }
17 else{
18 //father
19 sleep(3);
20 printf("I am father : %d!, ret: %d\n", getpid(), ret);
21 printf("count = %d\n",count);
22 }
23 sleep(1);
24 return 0;
25 }
输出结果为
fork进阶知识
int main(void)
{
int i=0;
printf("i son/pa ppid pid fpid/n");
//ppid指当前进程的父进程pid
//pid指当前进程的pid,
//fpid指fork返回给当前进程的值
for(i=0;i<2;i++){
pid_t fpid=fork();
if(fpid==0)
printf("%d child %4d %4d %4d/n",i,getppid(),getpid(),fpid);
else
printf("%d parent %4d %4d %4d/n",i,getppid(),getpid(),fpid);
}
return 0;
}
输出结果为:
分析:
for(i=0;i<2;i++){
pid_t fpid=fork();
if(fpid==0)
printf("%d child %4d %4d %4d/n",i,getppid(),getpid(),fpid);
else
printf("%d parent %4d %4d %4d/n",i,getppid(),getpid(),fpid);
}
i = 0时 当前进程pid = 6912 ,当前进程父进程2811 当前进程子进程6913
进程6912 进入下一次循环 i = 1 ,当前进程 6912 ,创建的子进程6914
(当前进程6912执行完毕,释放资源) 6912的子进程6914变成孤儿进程 6912父进程变为1
i = 0 6913进程也变成孤儿进程,父进程变为1 fpid = 0
i = 1此时6913变成父进程 fork子进程6918 6913执行完毕释放
6918变成孤儿进程 父进程为1
修改一下代码,在父进程前面在wait(NULL)等待子进程结束
1 #include <unistd.h>
2 #include <stdio.h>
3 int main(void)
4 {
5 int i = 0;
6 printf("i son/pa ppidt pid fpid\n");
7 for(i = 0;i<2;i++)
8 {
9 int fpid = fork();
10 if(fpid== 0){
11 // sleep(2);
12 printf("%d child %4d %4d %4d\n",i,getppid(),getpid(),fpid);
13 }
14 wait(NULL);
15 if(pid>0) {
16 printf("%d parent %4d %4d %4d\n",i,getppid(),getpid(),fpid);
17 }
18 }
19 return 0;
20 }
21
分析:
i = 0 父进程建立子进程 ,因为父进程阻塞所以子进程先运行,此时的进程是7348
由于wait的阻塞,子进程继续 此时i= 1 7348变为父进程 生成子进程7349 同样父进程7348被阻塞 当子进程7349 执行结束后 执行其父进程7348
来源:CSDN
作者:和平精英总指挥
链接:https://blog.csdn.net/weixin_44997886/article/details/104280447