user-0 提问: linux c 关于vfork正确执行的问题

回复:
user: user-0
content: 详见以下链接： http://www.embeddedlinux.org.cn/html/xianchengjincheng/201304/14-2542.html

user: user-0
content: 谢谢大家对我提问的回答，不过都是在解释 vfork，这些书上我都看过。  我想知道的答案是针对我的代码的，为什么会产生这种效果？ 从内存机制，系统的实现层面分析下，为什么两种情况执行结果是不同的

user: user-1
content: 引用 楼主 zwl6695125 的回复:本人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; }   linux 男人一下就知道

user: user-2
content: 现在假设你已经了解fork的行为了。 vfork与fork的两点区别： 1. vfork这个函数的意义就在于立马执行exec函数（当然你用作其它用途也未尝不可），因为vfork不会复制父进程的地址空间，因此可能比fork高效一些(之所以说“可能”，是因为在实现的时候，fork也未必会复制父进程的地址空间)。  在调用exec函数或exit之前，vfork出来的子进程都是在父进程的地址空间中运行的，因此对父进程的运行有影响。 2. 调用fork，父子进程的执行顺序不能保证，但是调用vfork的时候，会保证子进程先执行，直到子进程执行exec系列函数或调用exit

user: user-0
content: 引用 13 楼 zhao4zhong1 的回复:[quote=引用 12 楼 zwl6695125 的回复:] [quote=引用 5 楼 zhao4zhong1 的回复:] man 2 vfork  老师，我一个新手对诸多概念都不太熟悉，真的麻烦您帮我讲的通俗易懂点[/quote] 在shell命令行中输入以上命令，查看vfork的联机帮助。 会使用man命令是Linux程序员必须掌握的技能之一。[/quote]  查看手册，这个我还是会的。就是面对英文手册上写的不知道哪点是能解决我这个问题的。 所以，希望您能针对我这个问题，详细解释下

user: user-3
content: 引用 12 楼 zwl6695125 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] man 2 vfork  老师，我一个新手对诸多概念都不太熟悉，真的麻烦您帮我讲的通俗易懂点[/quote] 在shell命令行中输入以上命令，查看vfork的联机帮助。 会使用man命令是Linux程序员必须掌握的技能之一。

user: user-0
content: 引用 5 楼 zhao4zhong1 的回复:man 2 vfork  老师，我一个新手对诸多概念都不太熟悉，真的麻烦您帮我讲的通俗易懂点

user: user-0
content: 引用 10 楼 zxh707wk 的回复:[quote=引用 9 楼 zwl6695125 的回复:] [quote=引用 6 楼 zxh707wk 的回复:] 不用vfork行吗？  太调皮了！我是想知道到为什么，当然，不用也可以[/quote]不要写连自己也预测不了结果的代码！[/quote]  这个代码肯定不会用的，只是在学习阶段学点知识的

user: user-4
content: 引用 9 楼 zwl6695125 的回复:[quote=引用 6 楼 zxh707wk 的回复:] 不用vfork行吗？  太调皮了！我是想知道到为什么，当然，不用也可以[/quote]不要写连自己也预测不了结果的代码！

user: user-0
content: 引用 6 楼 zxh707wk 的回复:不用vfork行吗？  太调皮了！我是想知道到为什么，当然，不用也可以

user: user-0
content: 引用 3 楼 Idle_ 的回复:好像vfork() child process可以修改parent process的局部变量的。而child和parent是并行执行的，因此release时child的        strcpy(buf, "child : process write\n"); 可能在parent的        printf("havent run strcpy -> buf:%s", buf);之前执行了  对于vfork好像是会阻塞父进程，直到子进程结束的吧？

user: user-0
content: 引用 4 楼 user-6 的回复:你这个就是因为fork引起的输出缓冲区的紊乱  这个fork和vfork最近刚学，帮我解释详细点可以吗？

user: user-4
content: 不用vfork行吗？

user: user-5
content: 两个进程共享堆栈当然危险啦

user: user-0
content: 引用 15 楼 Idle_ 的回复:fork，顾名思义，就是分叉，fork返回后，产生的子进程和父进程一样从fork后一句开始执行，两者是并行的，vfork和fork基本一样，但是vfork省略了很多父进程内存页面的复制，因此vfork后子进程和父进程是共享堆栈的，也因此子进程对局部变量的修改可以影响父进程。vfork设计的主要目的是为了执行exec族命令的，因为它不需要复制父进程所有数据，因此加载速度快。但是你在vfork后执行其它语句却是非常危险的，因为很容易和父进程产生冲突。  可以从linux 系统实现的角度分析下为什么 \ “但是你在vfork后执行其它语句却是非常危险的，因为很容易和父进程产生冲突。”吗？

user: user-5
content: fork，顾名思义，就是分叉，fork返回后，产生的子进程和父进程一样从fork后一句开始执行，两者是并行的，vfork和fork基本一样，但是vfork省略了很多父进程内存页面的复制，因此vfork后子进程和父进程是共享堆栈的，也因此子进程对局部变量的修改可以影响父进程。vfork设计的主要目的是为了执行exec族命令的，因为它不需要复制父进程所有数据，因此加载速度快。但是你在vfork后执行其它语句却是非常危险的，因为很容易和父进程产生冲突。

user: user-3
content: man 2 vfork

user: user-6
content: 你这个就是因为fork引起的输出缓冲区的紊乱

user: user-5
content: 好像vfork() child process可以修改parent process的局部变量的。而child和parent是并行执行的，因此release时child的        strcpy(buf, "child : process write\n"); 可能在parent的        printf("havent run strcpy -> buf:%s", buf);之前执行了

user: user-0
content: 引用 1 楼 zhao4zhong1 的回复:在每个最后不带\n的printf后面加fflush(stdout);  没有作用……，麻烦您再帮我看看