请教fork的问题

发布于 2022-07-21 20:42:06 字数 4704 浏览 5 评论 8

请帮忙解释如下程序的输出:

  1. #include        <signal.h>
  2. #include        <unistd.h>
  3. #include        "ourhdr.h"
  4. int
  5. main(void)
  6. {
  7.         pid_t   pid;
  8.         printf("%s",getlogin(););
  9.         if ( (pid = fork()) < 0)
  10.                 err_sys("fork error");
  11.         else if (pid != 0) {            /* parent */
  12.                 sleep(2);
  13.                 exit(2);                                /* terminate with exit status 2 */
  14.         }
  15.         if ( (pid = fork()) < 0)
  16.                 err_sys("fork error");
  17.         else if (pid != 0) {
  18.                 sleep(4);
  19.                 abort();                                /* terminate with core dump */
  20.         }
  21.                                                                 /* second child */
  22.         if ( (pid = fork()) < 0)
  23.                 err_sys("fork error");
  24.         else if (pid != 0) {
  25.                 execl("/usr/bin/dd", "dd", "if=/boot", "of=/dev/null", NULL);
  26.                 exit(7);                                /* shouldn't get here */
  27.         }
  28.                                                                 /* third child */
  29.         if ( (pid = fork()) < 0)
  30.                 err_sys("fork error");
  31.         else if (pid != 0) {
  32.                 sleep(8);
  33.                 exit(0);                                /* normal exit */
  34.         }
  35.                                                                 /* fourth child */
  36.         sleep(6);
  37.         kill(getpid(), SIGKILL);        /* terminate with signal, no core dump */
  38.         exit(6);                                        /* shouldn't get here */
  39. }

复制代码
如果login:root, 输出为rootrootrootroot,为什么?

[ 本帖最后由 mq110 于 2006-7-31 16:32 编辑 ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

2022-07-26 06:11:07

原帖由 zxh5187406 于 2006-8-2 20:49 发表
这个不就是《APUE》的程序么...
-__-去看看fork出子进程相关的东西吧...

>>
>>
>>他这个应该不是fork造成的原因,你可以把printf("%s",getlogin());中的%s后面加上n就正常了
>>我把他的代码修改了一下,参见附件(没用的变量、函数都以删除)。
>>从实际的实验效果来看,应该是bash使用的readline造成的这个原因。
>>readline对于当前最新一行的的字符会动态检查,如果打印不含有n的字符,这个会先停留在readline
>>的最新的一行上面,但是你的输入又没有结束(readline以回车或者n为输入结束),所以fork出来的
>>几个进程都刷新了一遍printf("%s",getlogin());
>>
>>

把昨日还给我 2022-07-26 06:11:07

子进程继承了父进程的标准输出文件描述符并与父进程共享该文件的位置;
由于标准I/O库是行缓冲的(printf函数), 故父进程在调用fork之前的输出由于没有n仍保存在缓冲区里,
当fork后,这个缓冲区被子进程复制,所以有子父两次输出。可以把加个n或者fflush函数清空缓冲解决。

心清如水 2022-07-26 06:11:03

这个不就是《APUE》的程序么...
-__-去看看fork出子进程相关的东西吧...

維他命╮ 2022-07-26 06:10:51

呵呵~
把代码放在[ code ]与[ /code ]之间表情就没这么丰富了:)

很抱歉,是我没讲清楚。这个程序我是从《UNIX 环境高级编程》中摘下来的,
printf("%sn",getlogin());是我另加上去的。getlogin()是系统库函数,
返回用户的登录名,见<unistd.h>
ourhdr.h见附件

[ 本帖最后由 wuzhao 于 2006-8-2 17:35 编辑 ]

岁月染过的梦 2022-07-26 06:09:28

原帖由 Bayweb 于 2006-8-1 12:47 发表

>>
>>
>>还是不知道你的头文件是怎么书写的,估计问题就出在那里。我把你的程序改了一下,运行以后
>>没见到你说的情况,所以很可能还是你的头文件的原因。
>>
>>

...

>>
>>
>>我晕,都变成笑脸符了
>>
>>

萤火眠眠 2022-07-26 04:46:37

原帖由 wuzhao 于 2006-8-1 10:15 发表

ourhdr.h定义了一些常数和函数的原型,err_sys()等。printf("%s",getlogin() ; ) ;书写有误
至于dd的结果如何可暂不考虑。把printf("%s",getlogin() )改成printf("%sn" ...

>>
>>
>>还是不知道你的头文件是怎么书写的,估计问题就出在那里。我把你的程序改了一下,运行以后
>>没见到你说的情况,所以很可能还是你的头文件的原因。
>>
>>

改动如下:
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void
err_sys(char * msg)
{
    printf("%s", msg);
}

char *
getlogin(){
    char * msg_t;
    printf("Login:";
    scanf("%s", msg_t);
    return msg_t;
}

int
main(void)
{
    pid_t   pid;
    printf("%s",getlogin());
    if ( (pid = fork()) < 0)
    err_sys("fork error";
    else if (pid != 0) {            /* parent */
         sleep(2);
         exit(2);   /* terminate with exit status 2 */
    }
    if ( (pid = fork()) < 0)
         err_sys("fork error";
    else if (pid != 0) {
         sleep(4);
         abort();                                /* terminate with core dump */
    }
                                                            /* third child */
    if ( (pid = fork()) < 0)
         err_sys("fork error";
    else if (pid != 0) {
         sleep(;
         exit(0);                                /* normal exit */
    }

                                                            /* fourth child */
    sleep(6);
    kill(getpid(), SIGKILL);        /* terminate with signal, no core dump */
    exit(6);                                        /* shouldn't get here */
}

扬花落满肩 2022-07-24 19:47:21

原帖由 Bayweb 于 2006-7-31 22:23 发表
>>
>>
>>你的ourhdr.h是什么?printf("%s",getlogin() ; ) ; 是不是有些不妥?
>>dd的结果怎么没有出来?
>>
>>

ourhdr.h定义了一些常数和函数的原型,err_sys()等。printf("%s",getlogin() ; ) ;书写有误
至于dd的结果如何可暂不考虑。把printf("%s",getlogin() )改成printf("%sn",getlogin() )后只输出一个root,为什么?

美人如玉 2022-07-23 14:57:39

>>
>>
>>你的ourhdr.h是什么?printf("%s",getlogin() ; ) ; 是不是有些不妥?
>>dd的结果怎么没有出来?
>>
>>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文