linux c 关于vfork正确执行的问题

welong_zuo 2014-07-24 02:03:30
本人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;
}
...全文
368 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
welong_zuo 2014-07-31
  • 打赏
  • 举报
回复
详见以下链接: http://www.embeddedlinux.org.cn/html/xianchengjincheng/201304/14-2542.html
welong_zuo 2014-07-29
  • 打赏
  • 举报
回复
谢谢大家对我提问的回答,不过都是在解释 vfork,这些书上我都看过。 我想知道的答案是针对我的代码的,为什么会产生这种效果? 从内存机制,系统的实现层面分析下,为什么两种情况执行结果是不同的
nadleeh 2014-07-29
  • 打赏
  • 举报
回复
引用 楼主 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 男人一下就知道
shucheng36 2014-07-26
  • 打赏
  • 举报
回复
现在假设你已经了解fork的行为了。 vfork与fork的两点区别: 1. vfork这个函数的意义就在于立马执行exec函数(当然你用作其它用途也未尝不可),因为vfork不会复制父进程的地址空间,因此可能比fork高效一些(之所以说“可能”,是因为在实现的时候,fork也未必会复制父进程的地址空间)。 在调用exec函数或exit之前,vfork出来的子进程都是在父进程的地址空间中运行的,因此对父进程的运行有影响。 2. 调用fork,父子进程的执行顺序不能保证,但是调用vfork的时候,会保证子进程先执行,直到子进程执行exec系列函数或调用exit
welong_zuo 2014-07-25
  • 打赏
  • 举报
回复
引用 13 楼 zhao4zhong1 的回复:
[quote=引用 12 楼 zwl6695125 的回复:] [quote=引用 5 楼 zhao4zhong1 的回复:] man 2 vfork
老师,我一个新手对诸多概念都不太熟悉,真的麻烦您帮我讲的通俗易懂点[/quote] 在shell命令行中输入以上命令,查看vfork的联机帮助。 会使用man命令是Linux程序员必须掌握的技能之一。[/quote] 查看手册,这个我还是会的。就是面对英文手册上写的不知道哪点是能解决我这个问题的。 所以,希望您能针对我这个问题,详细解释下
赵4老师 2014-07-25
  • 打赏
  • 举报
回复
引用 12 楼 zwl6695125 的回复:
[quote=引用 5 楼 zhao4zhong1 的回复:] man 2 vfork
老师,我一个新手对诸多概念都不太熟悉,真的麻烦您帮我讲的通俗易懂点[/quote] 在shell命令行中输入以上命令,查看vfork的联机帮助。 会使用man命令是Linux程序员必须掌握的技能之一。
welong_zuo 2014-07-25
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
man 2 vfork
老师,我一个新手对诸多概念都不太熟悉,真的麻烦您帮我讲的通俗易懂点
welong_zuo 2014-07-25
  • 打赏
  • 举报
回复
引用 10 楼 zxh707wk 的回复:
[quote=引用 9 楼 zwl6695125 的回复:] [quote=引用 6 楼 zxh707wk 的回复:] 不用vfork行吗?
太调皮了!我是想知道到为什么,当然,不用也可以[/quote]不要写连自己也预测不了结果的代码![/quote] 这个代码肯定不会用的,只是在学习阶段学点知识的
707wk 2014-07-25
  • 打赏
  • 举报
回复
引用 9 楼 zwl6695125 的回复:
[quote=引用 6 楼 zxh707wk 的回复:] 不用vfork行吗?
太调皮了!我是想知道到为什么,当然,不用也可以[/quote]不要写连自己也预测不了结果的代码!
welong_zuo 2014-07-25
  • 打赏
  • 举报
回复
引用 6 楼 zxh707wk 的回复:
不用vfork行吗?
太调皮了!我是想知道到为什么,当然,不用也可以
welong_zuo 2014-07-25
  • 打赏
  • 举报
回复
引用 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好像是会阻塞父进程,直到子进程结束的吧?
welong_zuo 2014-07-25
  • 打赏
  • 举报
回复
引用 4 楼 pengzhixi 的回复:
你这个就是因为fork引起的输出缓冲区的紊乱
这个fork和vfork最近刚学,帮我解释详细点可以吗?
707wk 2014-07-25
  • 打赏
  • 举报
回复
不用vfork行吗?
阿呆_ 2014-07-25
  • 打赏
  • 举报
回复
两个进程共享堆栈当然危险啦
welong_zuo 2014-07-25
  • 打赏
  • 举报
回复
引用 15 楼 Idle_ 的回复:
fork,顾名思义,就是分叉,fork返回后,产生的子进程和父进程一样从fork后一句开始执行,两者是并行的,vfork和fork基本一样,但是vfork省略了很多父进程内存页面的复制,因此vfork后子进程和父进程是共享堆栈的,也因此子进程对局部变量的修改可以影响父进程。vfork设计的主要目的是为了执行exec族命令的,因为它不需要复制父进程所有数据,因此加载速度快。但是你在vfork后执行其它语句却是非常危险的,因为很容易和父进程产生冲突。
可以从linux 系统实现的角度分析下为什么 \ “但是你在vfork后执行其它语句却是非常危险的,因为很容易和父进程产生冲突。”吗?
阿呆_ 2014-07-25
  • 打赏
  • 举报
回复
fork,顾名思义,就是分叉,fork返回后,产生的子进程和父进程一样从fork后一句开始执行,两者是并行的,vfork和fork基本一样,但是vfork省略了很多父进程内存页面的复制,因此vfork后子进程和父进程是共享堆栈的,也因此子进程对局部变量的修改可以影响父进程。vfork设计的主要目的是为了执行exec族命令的,因为它不需要复制父进程所有数据,因此加载速度快。但是你在vfork后执行其它语句却是非常危险的,因为很容易和父进程产生冲突。
赵4老师 2014-07-24
  • 打赏
  • 举报
回复
man 2 vfork
pengzhixi 2014-07-24
  • 打赏
  • 举报
回复
你这个就是因为fork引起的输出缓冲区的紊乱
阿呆_ 2014-07-24
  • 打赏
  • 举报
回复
好像vfork() child process可以修改parent process的局部变量的。而child和parent是并行执行的,因此release时child的 strcpy(buf, "child : process write\n"); 可能在parent的 printf("havent run strcpy -> buf:%s", buf);之前执行了
welong_zuo 2014-07-24
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
在每个最后不带\n的printf后面加fflush(stdout);
没有作用……,麻烦您再帮我看看
加载更多回复(1)

69,336

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧