popen()系统调用在HP-Ux 11.11中挂起

时间:2011-04-26 11:43:55

标签: popen hp-ux

我有一个程序,通过popen()系统调用使用'/ usr / bin / lpstat'计算'Printer Queues Total'值。

{
    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()系统调用中挂起的原因,它将帮助我修改程序以满足我的要求。

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

2 个答案:

答案 0 :(得分:0)

人们期望并不总是有现实基础: - )

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

有两个可能的原因立即让人想起。

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

更多可能是管道的影响。我注意到的一件事是,一些过滤器(如grep)批量生产线以提高效率。所以,虽然popen本身可能会立即喷出它的线(好吧,直到它到达延迟位),grep保持线直到它得到一个足够大的块的事实可能会造成延误。

事实上,几乎可以肯定的是,直通wc,在从lpstat收到所有行之前,它无法生成任何输出(你无法弄清楚有多少行直到所有线路都已收到)。因此,即使popen只是等待第一个字符可用,这似乎就是挂起的地方。

通过简单地删除pipe-through-grep-and-wc位并查看发生的情况来测试它是一件简单的事情。


我想提出的另一点。你的printf语句后面没有换行符,即使它们有,也有些情况下输出可能仍然是完全缓冲的(因此在程序退出或填充缓冲区之前你可能看不到任何内容) )。

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

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

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

答案 1 :(得分:0)

当lpstat尝试从远程打印机检索信息时,听起来好像popen可能正在挂起。这个特殊问题有a fair amount of discussion。看一下那个帖子,特别是那个链接的那个。