免费注册 查看新帖 |

Chinaunix

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

对于这个程序结果的疑惑 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-04-16 09:25 |只看该作者 |倒序浏览
#include <sys/types.h>
#include <wait.h>

#include "errors.h"

int main( int argc, char *argv[] )
{
    int status ;
    char line[128];
    int seconds;
    pid_t pid;
    char message[64];

    while(1){
        printf("Alarm> ");
        if(fgets(line, sizeof(line), stdin) == NULL) exit(0);
        if(strlen(line) <= 1) continue;
        if (sscanf(line, "%d %64[^\n]", &seconds, message) < 2) {
        fprintf(stderr, "Bad command\n");
        }else {
            pid = fork();
            if(pid==(pid_t)-1)
                errno_abort("fork");
            if(pid==(pid_t)0) {
                sleep(seconds);
                printf("(%d) %s\n", seconds, message);
                exit(0);
            } else {
                        do {
                                pid = waitpid((pid_t)-1, NULL, WNOHANG);
                                if (pid == (pid_t)-1){
                                errno_abort("Wait for child");
                                }
                        }while(pid!=(pid_t)0);
                    }
                }
        }
}
这本来是个时间定时提示的程序,例如我输入 2 two seconds
运行程序2秒后应该打印two senconds,但对于输出的格式有些疑惑

当我输入
Alarm〉2 two seconds时2秒后输出
Alarm〉(2) two seconds
(另起一行,光标此时在这里等待下一次的定时输入)输入 3 three seconds
(3秒后输出)Alarm> (3) 3
我觉得格式不对啊,整个的过程应该是下面吧
Alarm〉2 two seconds时2秒后输出
(2) two seconds
Alarm> 3 three seconds
(3) three seconds
这是怎么回事呢

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
2 [报告]
发表于 2007-04-16 12:05 |只看该作者
原帖由 springzbz 于 2007-4-16 09:25 发表于 1楼  
#include <sys/types.h>
#include <wait.h>

#include "errors.h"

int main( int argc, char *argv[] )
{
    int status ;
    char line;
    int seconds;
    pid_t pid; ...

因为你的提示符在父进程中打印,但是 sleep 并打印睡眠了多长时间是在子进程中,而最后的 do-while 循环(在其中调用了 waitpid) 并不会使父进程等待子进程。

试下如下的代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/types.h>
  6. #include <wait.h>

  7. int
  8. main(void)
  9. {
  10.     char line[128];
  11.     int seconds;
  12.     pid_t pid, pid1;
  13.     char message[64];

  14.     while(1){
  15.         printf("Alarm> ");
  16.         if(fgets(line, sizeof(line), stdin) == NULL) exit(0);
  17.         if(strlen(line) <= 1) continue;
  18.         if (sscanf(line, "%d %64[^\n]", &seconds, message) < 2) {
  19.             fprintf(stderr, "Bad command\n");
  20.         }else {
  21.             pid1 = fork();
  22.             if(pid1 == (pid_t)-1)
  23.                 exit(1);
  24.             if(pid1 ==(pid_t)0) {
  25.                 sleep(seconds);
  26.                 printf("(%d) %s\n", seconds, message);
  27.                 exit(0);
  28.             } else {
  29.                 pid = waitpid(pid1, NULL, 0);
  30.                 if (pid == (pid_t)-1){
  31.                     exit(1);
  32.                 }           
  33.             }
  34.         }
  35.     }
  36.     return 0;
  37. }
复制代码

下面是运行的结果:
Alarm> 2 secs
(2) secs
Alarm> 3
Bad command
Alarm> 3 secs  
(3) secs
Alarm>

论坛徽章:
0
3 [报告]
发表于 2007-04-16 13:49 |只看该作者
你贴的这段程序我明白了,可是我贴的那个是POSIX程序设计里的例子,
对于 父进程的 程序
else {
                        do {
                                pid = waitpid((pid_t)-1, NULL, WNOHANG);
                                if (pid == (pid_t)-1){
                                errno_abort("Wait for child");
                                }
                        }while(pid!=(pid_t)0);
                    }

我还是有些不明白以下几点:
1、父进程的pid = waitpid((pid_t)-1, NULL, WNOHANG);
     -1指的 不是 等待 任意子进程 么 ?为什么 不会 等待 上面的子进程 呢 ?
2. WNOHANG做何解释 ?难道和这个有关?
3.对于 这一段书中的注释是 (我没太看明白 )
  我门调用waitpid函数 ,并设置 WNOHANG.如果有子进程终止,该函数 调用回收该子进程的资源 ;如果没有子进程终止,该函数立即返回pid=0.父进程继续回收终止的子进程直到没有子进程终止,当循还终止的时候,main函数继续循环到while(1)

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
4 [报告]
发表于 2007-04-16 14:28 |只看该作者
原帖由 springzbz 于 2007-4-16 13:49 发表于 3楼  
1、父进程的pid = waitpid((pid_t)-1, NULL, WNOHANG);
     -1指的 不是 等待 任意子进程 么 ?为什么 不会 等待 上面的子进程 呢 ?
2. WNOHANG做何解释 ?难道和这个有关?
3.对于 这一段书中的注释是 (我没太看明白 )
  我门调用waitpid函数 ,并设置 WNOHANG.如果有子进程终止,该函数 调用回收该子进程的资源;如果没有子进程终止,该函数立即返回pid=0.父进程继续回收终止的子进程直到没有子进程终止,当循还终止的时候,main函数继续循环到while (1)


下面是 waitpid(3) 手册中关于其返回值的一段:
       If  waitpid()  was invoked with WNOHANG set in options, it has at least one child process
       specified by pid for which status is not available, and status is not available for any process
       specified by pid, 0  is  returned. Otherwise, (pid_t)-1 shall be returned, and errno set to indicate
       the error.

上面的引文应该可以解楼主之惑了。

另根据如上叙述,楼主还可以把最后调用 waitpid 的 do-while 循环的条件判断改为 while(pid == (pid_t)0),这样也可以达到目的。

[ 本帖最后由 MMMIX 于 2007-4-16 15:21 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP