【问题标题】:popen() system call hangs in HP-Ux 11.11popen() 系统调用在 HP-Ux 11.11 中挂起
【发布时间】:2011-04-26 11:43:54
【问题描述】:

我有一个程序通过 popen() 系统调用使用“/usr/bin/lpstat”计算“打印机队列总数”值。

{
    int                     n=0;
    FILE                    *fp=NULL;

    printf("Before popen()");
    fp = popen("/usr/bin/lpstat -o | grep '^[^ ]*-[0-9]*[ \t]' | wc -l", "r");
    printf("After popen()");

    if (fp == NULL)
    {
            printf("Failed to start lpstat - %s", strerror(errno));
            return -1;
    }

    printf("Before fscanf");
    fscanf(fp, "%d", &n);
    printf("After fscanf");

    printf("Before pclose()");
    pclose(fp);
    printf("After pclose()");

    printf("Value=%d",n);
    printf("=== END ===");
    return 0;
}

注意:在命令行中,“/usr/bin/lpstat”命令会挂起一段时间,因为网络中有许多可用的打印机。

这里的问题是,执行在 popen() 系统调用处挂起,而我希望它在 fscanf() 处挂起,它从文件流 fp 中读取输出。

如果有人能告诉我 popen() 系统调用挂起的原因,它将帮助我修改程序以满足我的要求。

感谢您花时间阅读这篇文章和您的努力。

【问题讨论】:

  • 除此之外,\t 应该是\\t

标签: popen hp-ux


【解决方案1】:

人们期望在现实中并不总是有根据:-)

您正在运行的命令在完成之前实际上不会生成任何输出。这就是为什么它似乎挂在popen 而不是fscanf

有两个可能的原因立即浮现在脑海中。

第一个是它以这种方式实现,popen 在传递第一行之前捕获完整的输出。根据我对 UNIX 的了解,这似乎不太可能,但我不能确定。

更多可能是管道的影响。我注意到的一件事是一些过滤器(如grep)为了提高效率而分批生产。所以,虽然popen 本身可能会立即吐出它的线路(好吧,直到它到达延迟位),事实上grep 一直坚持线路直到它获得足够大的块可能导致延迟。

事实上,几乎可以肯定是 pipe-through-wc,它无法生成 any 输出,直到从 lpstat 接收到所有行(直到所有行都线路已收到)。因此,即使 popen 只是等待第一个 字符 可用,这似乎就是问题所在。

只需删除 pipe-through-grep-and-wc 位并查看会发生什么,即可对此进行测试。


还有一点我想提出。您的printf 语句后面没有换行符,即使有,在某些情况下输出可能仍被完全缓冲(因此在该程序退出或缓冲区填满之前您可能看不到任何内容)。

我会先将它们更改为以下形式:

printf ("message here\n"); fflush (stdout); fsync (fileno (stdout));

以确保它们在继续之前完全刷新。我讨厌这是对缓冲问题的简单误解:-)

【讨论】:

  • 您好 paxdiablo,感谢您的时间和回复。实际上,这发生在我的一个客户环境中。为了复制我所做的相同的事情,我编写了一个脚本“/usr/bin/lpstat”,它除了休眠 2 分钟之外什么都不做,并且会回显一个示例 lpstat 输出。在我的设置中,我看到挂起是在 fscanf() 调用中。所以这是我期望的基础。在 popen() 之前(TIME=Tue Apr 26 00:06:05 2011),在 popen() 之后(TIME=Tue Apr 26 00:06:05 2011),在 fscanf 之前(TIME=Tue Apr 26 00:06:05 2011 ) 在 fscanf 之后(TIME=Tue Apr 26 00:08:05 2011)。
  • 那些 printf() 语句仅用于我的测试程序。但是在客户案例中,我们有一个适当的日志记录来处理冲洗。
【解决方案2】:

在 lpstat 尝试从远程打印机检索信息时,听起来好像 popen 可能挂起。在这个特定问题上有a fair amount of discussion。看看那个线程,尤其是那些与之相关的线程。

【讨论】:

  • 您好,Mdec,感谢您提供的信息。您提供的线程是信息性的。但我主要关心的是为什么使用 popen() 执行命令在 popen() 调用时挂起,理想情况下,它会创建一个进程并执行命令并返回一个文件流作为输出。理想情况下 fscanf() 应该阻塞输出文件流。这有点难以理解。如果我遗漏了某些东西的基本原理,请原谅。非常感谢您提供的信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多