linux c 关于vfork正确执行的有关问题
linux c 关于vfork正确执行的问题
本人linux新手,没多少分可以给,希望大牛们看在都是搞技术的层面上帮我解决下问题。
在编译下述代码的时候
如果已经宏定义了DEBUG
产生如下结果:
child : process id is 4287
child : parent process id is 4286
havent run strcpy -> buf:THIS IS parent process line
have run strcpy -> buf:parent : process line
parent : process id is 4286
如果没有宏定义DEBUG
产生如下结果:
child : process id is 4223
child : parent process id is 4222
havent run strcpy -> buf:child : process write
have run strcpy -> buf:parent : process line
parent : process id is 4222
point is : 为什么 “havent run strcpy ->” 所在行的显示会有不同 ?
编译环境:ubuntu 10.04.3, gcc
代码如下
------解决方案--------------------
man 2 vfork
------解决方案--------------------
不用vfork行吗?
------解决方案--------------------
不要写连自己也预测不了结果的代码!
------解决方案--------------------
在shell命令行中输入以上命令,查看vfork的联机帮助。
会使用man命令是Linux程序员必须掌握的技能之一。
------解决方案--------------------
fork,顾名思义,就是分叉,fork返回后,产生的子进程和父进程一样从fork后一句开始执行,两者是并行的,vfork和fork基本一样,但是vfork省略了很多父进程内存页面的复制,因此vfork后子进程和父进程是共享堆栈的,也因此子进程对局部变量的修改可以影响父进程。vfork设计的主要目的是为了执行exec族命令的,因为它不需要复制父进程所有数据,因此加载速度快。但是你在vfork后执行其它语句却是非常危险的,因为很容易和父进程产生冲突。
------解决方案--------------------
两个进程共享堆栈当然危险啦
------解决方案--------------------
现在假设你已经了解fork的行为了。
vfork与fork的两点区别:
1. vfork这个函数的意义就在于立马执行exec函数(当然你用作其它用途也未尝不可),因为vfork不会复制父进程的地址空间,因此可能比fork高效一些(之所以说“可能”,是因为在实现的时候,fork也未必会复制父进程的地址空间)。 在调用exec函数或exit之前,vfork出来的子进程都是在父进程的地址空间中运行的,因此对父进程的运行有影响。
2. 调用fork,父子进程的执行顺序不能保证,但是调用vfork的时候,会保证子进程先执行,直到子进程执行exec系列函数或调用exit
本人linux新手,没多少分可以给,希望大牛们看在都是搞技术的层面上帮我解决下问题。
在编译下述代码的时候
如果已经宏定义了DEBUG
产生如下结果:
child : process id is 4287
child : parent process id is 4286
havent run strcpy -> buf:THIS IS parent process line
have run strcpy -> buf:parent : process line
parent : process id is 4286
如果没有宏定义DEBUG
产生如下结果:
child : process id is 4223
child : parent process id is 4222
havent run strcpy -> buf:child : process write
have run strcpy -> buf:parent : process line
parent : process id is 4222
point is : 为什么 “havent run strcpy ->” 所在行的显示会有不同 ?
编译环境:ubuntu 10.04.3, gcc
代码如下
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEBUG
char buf[100];
int main(int argc, char **argv)
{
int fd;
#ifdef DEBUG
pid_t pid = vfork();
#else
pid_t pid = -1;
#endif
if((fd = open("temp", O_CREAT | O_TRUNC | O_RDWR, S_IRWXU)) == -1)
{
perror("open file error !\n");
return 0;
}
strcpy(buf, "THIS IS parent process line\n");
#ifdef DEBUG
if(pid == 0)
#else
if( (pid = vfork()) == 0)
#endif
{
strcpy(buf, "child : process write\n");
printf("\n");
printf("child : process id is %d\n", getpid());
printf("child : parent process id is %d\n\n", getppid());
write(fd, buf, strlen(buf));
close(fd);
exit(0); //child process must exit while work done
}
else
{
printf("havent run strcpy -> buf:%s", buf);
strcpy(buf, "parent : process line\n");
printf("have run strcpy -> buf:%s", buf);
printf("parent : process id is %d\n", getpid());
write(fd, buf, strlen(buf));
printf("\n");
close(fd);
}
return 0;
}
------解决方案--------------------
man 2 vfork
------解决方案--------------------
不用vfork行吗?
------解决方案--------------------
不要写连自己也预测不了结果的代码!
------解决方案--------------------
man 2 vfork
老师,我一个新手对诸多概念都不太熟悉,真的麻烦您帮我讲的通俗易懂点
在shell命令行中输入以上命令,查看vfork的联机帮助。
会使用man命令是Linux程序员必须掌握的技能之一。
------解决方案--------------------
fork,顾名思义,就是分叉,fork返回后,产生的子进程和父进程一样从fork后一句开始执行,两者是并行的,vfork和fork基本一样,但是vfork省略了很多父进程内存页面的复制,因此vfork后子进程和父进程是共享堆栈的,也因此子进程对局部变量的修改可以影响父进程。vfork设计的主要目的是为了执行exec族命令的,因为它不需要复制父进程所有数据,因此加载速度快。但是你在vfork后执行其它语句却是非常危险的,因为很容易和父进程产生冲突。
------解决方案--------------------
两个进程共享堆栈当然危险啦
------解决方案--------------------
现在假设你已经了解fork的行为了。
vfork与fork的两点区别:
1. vfork这个函数的意义就在于立马执行exec函数(当然你用作其它用途也未尝不可),因为vfork不会复制父进程的地址空间,因此可能比fork高效一些(之所以说“可能”,是因为在实现的时候,fork也未必会复制父进程的地址空间)。 在调用exec函数或exit之前,vfork出来的子进程都是在父进程的地址空间中运行的,因此对父进程的运行有影响。
2. 调用fork,父子进程的执行顺序不能保证,但是调用vfork的时候,会保证子进程先执行,直到子进程执行exec系列函数或调用exit