免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2465 | 回复: 4
打印 上一主题 下一主题

fork创建进程的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-16 14:19 |只看该作者 |倒序浏览
大大们好,新手刚刚学习linux下的编程。
碰到一个问题,特向大大们请教:

#include "apue.h"
#include <sys/wait.h>

void
pr_exit(int status)
{
    if (WIFEXITED(status))
        printf("normal termination, exit status = %d\n",
                WEXITSTATUS(status));
    else if (WIFSIGNALED(status))
        printf("abnormal termination, signal number = %d%s\n",
                WTERMSIG(status),
#ifdef  WCOREDUMP
                WCOREDUMP(status) ? " (core file generated)" : "");
#else
                "");
#endif
    else if (WIFSTOPPED(status))
        printf("child stopped, signal number = %d\n",
                WSTOPSIG(status));
}





------------------------------------

#include "apue.h"
#include <sys/wait.h>

int
main(void)
{
    pid_t   pid;
    int     status;

    if ((pid = fork()) < 0)
        err_sys("fork error");
    else if (pid == 0)              /* child */
        exit(7);

    if (wait(&status) != pid)       /* wait for child */
        err_sys("wait error");
    pr_exit(status);                /* and print its status */

    if ((pid = fork()) < 0)
        err_sys("fork error");
    else if (pid == 0)              /* child */
        abort();                    /* generates SIGABRT */

    if (wait(&status) != pid)       /* wait for child */
        err_sys("wait error");
    pr_exit(status);                /* and print its status */

    if ((pid = fork()) < 0)
        err_sys("fork error");
    else if (pid == 0)              /* child */
        status /= 0;                /* divide by 0 generates SIGFPE */

    if (wait(&status) != pid)       /* wait for child */
        err_sys("wait error");
    pr_exit(status);                /* and print its status */

    exit(0);
}


------------------------------
RESULTS:

$ ./a.out
   normal termination, exit status = 7
   abnormal termination, signal number = 6 (core file generated)
   abnormal termination, signal number = 8 (core file generated)


关于linux下的进程创建机制我也有一定的理解。

问题1:
linux采用的是copy-on-write机制,那么是不是说上面的例子中,子进程和父进程代码都是共享的一份代码喽?毕竟,没有变量的改写之类的啊。。。

问题2:
对于上面的代码,关于子进程的判断的时候,就只有一句代码:
if (pid == 0) ...
我理解的是,
   1》 exit(7);    2》 abort(); 3》status /= 0;
这三句代码毕竟是从上向下依次执行的,那么
就如果问题1中的假设成立的话,那么
exit(7);将是最先被执行的代码,剩下的2》3》都不会被执行。

这里我最难理解的就是共享一份代码,linux是依据什么去判断那三个不同的进程,并出现不同的执行结果呢?
   

============================================================

大大们linux下编程有经验的多,希望能帮一帮小菜鸟,大家一起进步。谢谢大大们了。。


论坛徽章:
0
2 [报告]
发表于 2009-03-16 14:32 |只看该作者
各个进程都有自己的运行空间,不知道这样说你明白了没有。。。

论坛徽章:
0
3 [报告]
发表于 2009-03-16 14:46 |只看该作者

回复 #2 alexhappy 的帖子

恩,我知道,在进程切换的时候,正是由于CR3寄存器的作用,才可以使得同样的线性地址对于不同的进程来说对应的内容是不一样的。所以,不同的进程有不同的地址空间。

那是不是说,虽然只有一份代码(是不是呢??? ),但是由于每一个进程都有一个CR3来维护,所以,才出现了内存中的同一份代码,但是却不同的运行结果???

还有,那既然只有一份代码,但是linux是怎么区分的呢?毕竟,上面的代码中,区分子进程的代码只有一个 if (pid == 0) 。。。  这样的语句。

LZ的大大再指点一下吧?谢谢了

论坛徽章:
0
4 [报告]
发表于 2009-03-16 16:04 |只看该作者
看了网上的文章,现在晓得是怎么一回事了。

其实,关键还是在一点:那就是FORK()函数之后,才开始分出不同的进程。fork就是叉子吗,那fork就可以形象的理解为分叉,也就是说,子进程和父进程在这一点开始出现差异。

再就是,fork()之后,父进程和子进程的好些"东西"相同. 关键还在于这里的“东西”的理解。

这里所说的相同的地方,那就是运行环境的完全相同,包括变量,空间分配,特别是正在执行的语句等等都相同
。也就是fork之后就开始出现分叉了。

最后上一张图片,大家看看。(图片太差劲了,大家凑或着看吧,呵呵。。。

1.PNG (6.19 KB, 下载次数: 5)

1.PNG

论坛徽章:
0
5 [报告]
发表于 2009-03-16 16:08 |只看该作者
还有一点,那就是if (pid == 0) 。。。这里的子进程的判断问题。

因为,不同的进程中都有一个pid的变量,那么查看子进程A中的pid时,子进程B中的pid的值你当然不可以查看(windows下可以用ReadProcessMemory查看,linux下本人刚刚接触,就不太晓得了,估计也会有内存读取之类的函数)。

所以,依据pid区分子进程的时候,向我一样的菜鸟最好还是先画一个图,这样也便于理解,呵呵。


菜鸟的问题,麻烦大大们了,谢谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP