fork函数相关资源复制问题验证
创始人
2024-02-08 11:49:35

前言

        fork是什么?克隆当前的进程,然后创建一个子进程。本文分几个验证实例代码,主要是为解决验证一些小问题。

一 fork与文件描述符

fork之前打开一个文件的测试。

问题:fork之后,父进程关闭文件,子进程是否还可以正常写文件?

#include 
#include 
#include 
#include 
#include 
#include 
#include int main()
{int fd;char buf[100];int count = 0;int pid;fd = open("hello.txt",O_RDWR|O_CREAT,0666);if(fd < 0){perror("open");return -1;}printf("open ok\n");pid = fork();if(pid == -1){perror("fork");exit(-1);}if(pid > 0){printf("parent:pid = %d\n",getpid());close(fd);}else{while(1){sprintf(buf,"count = %d\n",count++);write(fd,buf,strlen(buf));sleep(1);}}while(1)sleep(1);return 0;
}

        这个程序得出的结果是,子进程会不停的向文件中写内容,即便父进程关闭了fd。这说明,fork执行以后,子进程继承了父进程的资源。并且继承了文件描述符,子进程与父进程在fork以后,就是两个不同的进程了。

这时,杀死父进程,子进程将被系统进程接管。

杀死子进程呢?子进程将变成僵尸进程。如何处理僵尸进程呢?暂时先不讨论这个问题。

二 fork与线程

fork之前创建一个线程。

问题:fork之后,子进程是否拥有一个该线程的复制?

测试实例:fork.c

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include void * mythread(void *arg)
{while(1){printf("pid = %d\n",getpid());sleep(1);}return NULL;
}int main()
{int fd;char buf[100];int count = 0;int pid;pthread_t t;fd = open("hello.txt",O_RDWR|O_CREAT,0666);if(fd < 0){perror("open");return -1;}printf("open ok\n");pthread_create(&t,NULL,mythread,NULL);pid = fork();if(pid == -1){perror("fork");exit(-1);}if(pid > 0){printf("parent:pid = %d\n",getpid());close(fd);}else{while(1){sprintf(buf,"count = %d\n",count++);write(fd,buf,strlen(buf));sleep(1);}}while(1)sleep(1);return 0;
}

编译

gcc fork.c -pthread

 测试结果:

lkmao@ubuntu:~/01$ ./a.out
open ok
pid = 124353
parent:pid = 124353
child:pid = 124355
pid = 124353
pid = 124353
pid = 124353
pid = 124353
pid = 124353
pid = 124353
pid = 124353
pid = 124353
pid = 124353
pid = 124353
pid = 124353

 执行pstree -p命令:

 {a.out}124354,就是创建的线程,它只有一个。

三 fork与malloc

fork之前使用malloc分配内存。fork之后,父进程free这块内存,请问,子进程是否还有该内存的使用权?

一句话:每个进程都拥有,且独立使用4GB的虚拟内存空间。还像是这么说的。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include void * mythread(void *arg)
{while(1){printf("pid = %d\n",getpid());sleep(1);}return NULL;
}int main()
{int fd;char* buf;int count = 0;int pid;pthread_t t;fd = open("hello.txt",O_RDWR|O_CREAT|O_TRUNC,0666);if(fd < 0){perror("open");return -1;}printf("open ok\n");buf = malloc(100);pthread_create(&t,NULL,mythread,NULL);pid = fork();if(pid == -1){perror("fork");exit(-1);}if(pid > 0){printf("parent:pid = %d\n",getpid());free(buf);close(fd);}else{printf("child:pid = %d\n",getpid());while(1){sprintf(buf,"count = %d\n",count++);write(fd,buf,strlen(buf));sleep(1);}}while(1)sleep(1);return 0;
}

这个测试结果和实例1一样。

这样验证可能还是不太好,从新写验证代码,fork之前对buf赋值 "count = 0",fork之后,父进程修改buf。然后,子进程等待1秒,然后子进程打印buf,思考子进程打印的buf是什么?不用想的看结果吧。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include int main()
{char* buf;int count = 0;int pid;pthread_t t;buf = malloc(100);sprintf(buf,"count = %d\n",count++);pid = fork();if(pid == -1){perror("fork");exit(-1);}if(pid > 0){printf("buf = %p\n",buf);printf("parent:pid = %d\n",getpid());sprintf(buf,"pid = %d\n",getpid());printf("parent buf:%s\n",buf);}else{sleep(1);printf("buf = %p\n",buf);printf("child:pid = %d\n",getpid());printf("child buf:%s\n",buf);}while(1)sleep(1);return 0;
}

测试结果:虽然父子进程的buf地址相同,但是父子进程的buf中的内容,是完全不同的。这就是为什么说,每个进程的虚拟地址空间独立的原因吧。

lkmao@ubuntu:~/01$ gcc fork.c
lkmao@ubuntu:~/01$ ./a.out
buf = 0xe01010
parent:pid = 126902
parent buf:pid = 126902buf = 0xe01010
child:pid = 126903
child buf:count = 0

 

小结

        暂时想到这几个问题,关于如何处理僵尸进程呢?这个问题,下次研究。

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...