调用外部脚本时的奇怪行为

时间:2014-09-25 09:16:44

标签: c++ linux multithreading bash console

我的C ++程序只是一个非常简单的while循环,我在其中使用getline()阻塞函数从控制台(标准输入,stdin)获取用户命令。我偶尔会为其他目的调用外部bash脚本。该脚本与用户所做的事情没有直接关系,它只是在文件系统上做了一些事情,但它必须在控制台标准输出(stdout)中打印文本行,以通知用户计算结果。

我得到的是,一旦脚本启动并将内容打印到stdout,getline()函数就表明它是非阻塞的(它应该阻塞直到用户输入一些文本)。结果,while(1)开始全速旋转,CPU使用率猛增至接近100%。

我将问题缩小到单个C ++源文件,以同样的方式再现问题,这里是:

#include<iostream>
#include<string>
#include<sstream>
#include<iostream>
#include<stdlib.h>
#include<stdio.h>

int main(void)
{

    int pid = fork(); // spawn

    if(pid > 0)
    {   
        // child thread
        system("sleep 5; echo \"you're screwed up!!!\"");
    }
    else
    {       
        // main thread
        std::string input;
        while(1)
        {
            std::cout << std::endl << "command:";
            getline(std::cin, input);
        }
    }
}  

在这种特殊情况下,程序在5秒后开始在stdout上发送垃圾邮件“\ n命令:”,并且阻止它的唯一方法是发送SIGKILL信号。有时,在程序开始发送文本行之前,您必须按键盘上的某些键。

让我们运行此代码10秒钟,然后按键盘上的任意键。确保准备好从另一个控制台向该进程发出SIGKILL信号。您可以使用命令killall -9 progname

3 个答案:

答案 0 :(得分:1)

尝试更改代码的以下行

if (pid > 0)

if (pid == 0)

fork()将0返回给孩子,将孩子的pid返回给父母。在您的示例中,您在父级中运行system()并退出父级。然后,孩子变成孤儿进程在while(1)循环中运行,我猜这是在混乱stdin,stdout。

我已修改您的程序以在子进程中运行system()

答案 1 :(得分:1)

基本问题:

if(pid > 0)
    {   
        // child thread
        system("sleep 5; echo \"you're screwed up!!!\"");
    }

这是父母。 ;)孩子获得pid0

答案 2 :(得分:1)

您是否检查过failbit或eof是否已设置?