Chinaunix首页 | 论坛 | 博客
  • 博客访问: 680048
  • 博文数量: 183
  • 博客积分: 9166
  • 博客等级: 中将
  • 技术积分: 1920
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-31 16:17
文章分类

全部博文(183)

文章存档

2010年(159)

2009年(24)

分类:

2009-11-14 07:28:56

        调用vfork()创建子进程后,子进程共享父进程的地址空间,并且子进程先运行,当它调用exec或exit之后,父进程才被调度运行,但是如果子进程调用exec函数后,系统就把当前的代码段替换成新的程序代码,所以按道理是父进程没办法继续执行了。
看下面的代码:
(1)程序processimage.c
#include

int main(int argc,char *argv[],char **environ)
{
  int i;
    printf("processimage\n");
    printf("pid = %d,parentpid = %d\n",getpid(),getppid());
    for(i = 0;i < argc;i++)
        printf("argv[%d]:%s\n",i,argv[i]);
    return 0;
}
(2)程序execve.c
#include
#include
#include
#include

int main(int argc,char *argv[],char **environ)
{
    pid_t pid;
    int stat_val;
    pid = vfork();
    switch(pid){
        case -1:printf("error\n");
                    exit(0);
        case 0: printf("child is running\n");
                    execve("processimage",argv,environ);
                    exit(0);
        default:sleep(2);
                   printf("parent is running\n");
                   break;
    }
    wait(&stat_val);
    exit(0);
}
运行结果:
child is running
processimage
pid = 4061,parentpid = 4060
argv[0]:./exec01
parent is running           //为什么这一句也会输出?
请各位指教。。。




*******************************************************************************************

>> 调用vfork()创建子进程后,子进程共享父进程的地址空间,并且子进程先运行,当它调用exec或exit之后,父进程才被调度运行,但是如果子进程调用exec函数后,系统就把当前的代码段替换成新的程序代码,所以按道理是父进程没办法继续执行了。
> 这个是Linux下Copy On Write的功劳。子进程调用exec时,内核注意到要写入的区域是跟父进程共享的,并且置有COW标记,就不会直
> 接往里头写,而是给子进程分配新的空间,修改PCB等相关数据结构,然后将执行体加载到新的空间里。
> 其实这个子进程共享父进程的地址空间和Copy On Write是Linux的一个优化手段,如果严格按照POSIX语义(Linux不是原教旨主义
> 者……),vfork之后是要复制整个内存空间而不会共享的。

我不是很理解你想说什么,但从第一句话来看,是错的。

vfork()没有使用COW,它使用的是CLONE_VM,在copy_mm()中这个跳过了复制新的mm_struct。
为什么execve()之后就可以呢?因为它在bprm_mm_init()里又创建了一个新的mm_struct。

man vfork中有提到:

       Under  Linux,  fork(2) is implemented using copy-on-write pages, so the
       only penalty incurred by fork(2) is the time  and  memory  required  to
       duplicate  the parent’s page tables, and to create a unique task struc-
       ture for the child.
       .....
       BSD introduced the vfork() system call, which
       did not fully copy the address space of the parent  process,  but  bor-
       rowed  the  parent’s  memory  and  thread  of  control  until a call to
       execve(2) or an exit occurred.
阅读(2686) | 评论(0) | 转发(0) |
0

上一篇:一个C语言的程序

下一篇:switch问题

给主人留下些什么吧!~~