【问题标题】:weird behaviour when calling external script调用外部脚本时的奇怪行为
【发布时间】:2014-09-25 09:16:43
【问题描述】:

我的 C++ 程序只是一个非常简单的 while 循环,我在其中使用 getline() 阻塞函数从控制台(标准输入、标准输入)获取用户命令。为了其他目的,我必须时不时地调用一个外部 bash 脚本。该脚本与用户的操作没有直接关系,它只是在文件系统上做一些事情,但它必须在控制台标准输出 (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 秒后程序开始在标准输出上发送垃圾邮件“\ncommand:”,而阻止它的唯一方法是发送 SIGKILL 信号。有时您必须在程序开始发送垃圾邮件之前按键盘上的某些键。

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

【问题讨论】:

  • 你在哪个环境下试过?我试着运行你的程序,我得到了command:you're screwed up!!!,程序退出了。
  • Linux CentOS6.然而,它实际上并没有退出。尝试按该控制台上的一些键,它应该开始发送垃圾邮件。

标签: c++ linux multithreading bash console


【解决方案1】:

你检查是否设置了failbit或eof?

【讨论】:

  • 不错的收获! std::cin.good() 返回 false,因此设置了 eof、fail 或 bad bit。
【解决方案2】:

尝试更改以下代码行

if (pid > 0)

if (pid == 0)

fork() 将 0 返回给子节点,将子节点的 pid 返回给父节点。在您的示例中,您在父级中运行 system() 并退出父级。然后,孩子成为在while(1) 循环中运行的孤儿进程,我猜这会弄乱标准输入、标准输出。

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

【讨论】:

  • mm 没关系。它解决了概念证明程序上的问题,但没有解决原始程序上的问题。在原来我使用 boost::thread 并且没有这样的 pid 可以检查
  • 请确保您在子线程中运行system(),在父线程中运行getline()
  • 所以主要问题是孩子成为孤儿并开始弄乱标准输出?请问,你能更深入地解释发生了什么吗?为什么 getline() 开始表现出非阻塞函数?
【解决方案3】:

基本问题:

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

这是家长。 ;) 孩子得到pid : 0

【讨论】:

  • 查看我对上述答案的评论
  • @G_G 我们回答了这个问题。你得到了你所问的答案。因此,如果这个答案是正确的,请接受它们 - 并提出另一个问题 - 使用您需要帮助的真实代码..
猜你喜欢
  • 2020-02-06
  • 1970-01-01
  • 2019-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
相关资源
最近更新 更多