fork函数

fork函数,对于子进程来说

1.复制问题

它会完完全全复制父进程的代码段,数据段,堆栈段等,子进程与父进程虽然虚拟地址不同,但是二者完全使用同一块物理空间。一般来说,代码段是不会变化的,但,是如果数据段或其他发生变化时,系统会为这个进程分配出一块新的物理空间,所以,另一个进程的数据不会受到影响,这个也叫做写时复用。(如果两个进程,没有一个进程打算改变数据段,堆栈段等,那么二者就会一直使用同一块物理空间,但是一旦一个进程想要发生改变,那么会获得一块新的物理空间)。

2.执行问题

子进程不仅仅复制上面那些,而且还会将程序计数器中的内容复制过来,所以,子进程实际上是从fork()之后才执行的,fork()之前的代码段是不执行的,但是父进程已经执行完的结果放在数据段是被子进程直接拿来用的。

例子:

 

1.

include <sys/ioctl.h>

char buf[128]="i am user................";
char buf1[128];
char buf2[128];
int main(int argc, const char *argv[])
{
int fd;
pid_t pid,pid1;
fd = open("hello",O_RDWR);
if(fd == -1){
perror("open hello is fail\n");
return -1;
}
pid = fork();
if(pid < 0){
perror("fork error");
return -1;
}else if(pid == 0){
write(fd,buf,sizeof(buf));
}else{
sleep(1);

read(fd,buf1,sizeof(buf1));

printf("1111111  data = %s\n",buf1);

}

       在父进程中已经执行了open函数了,在open调用sys_open函数的过程中,已经将fd中填充好file_operations方法了,也就是此时已经可以对fd这个文件进行读写操作了,因为它里面已经填充上方法了,而子进程虽然不能执行fork之前的内容,因为fork之后产生了子进程,虽然子进程将父进程的代码段数据段完全复制过来,但是,程序计数器的内容也完全复制过来,所以,从fork之后开始执行剩下的代码,但不是说子进程没有办法执行open函数就没办法执行read函数了,因为在父进程执行的过程中已经对这个fd填充好操作方法了,而这个fd放在数据段,这个文件的驱动程序中已经填充好操作方法了,子进程只要找到这个文件即可,就可以直接进行读写操作,而不用并且也不能再执行这个open函数。也就是说代码段是按照程序计数器中的内容向下执行,数据段是按照fork之前父进程留下的数据段中的内容进行的。

2.

#include<stdio.h>
#include<unistd.h>
int main(int argc, const char *argv[])
{
pid_t pid;
printf("hello\n");
int a=2;
int b=3;
int c=a+b;
pid=fork();
if(pid==-1)
{
perror("fork error\n");
}
else if(pid==0)
{
printf("子进程c=%d\n",c);
}
else
{
printf("父进程c=%d\n",c);
}
return 0;

}

这里如果hello那里不加上\n,那么缓冲区中的hello也会被子进程复制,那么子进程在运行时,也会输出这个hello,因为子进程还把这个缓冲区复制了,如果父进程缓冲区刷新,那么子进程复制的缓冲区中就没有hello,不会输出hello,因为子进程本身不执行fork之前的这段代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值