【问题标题】:Continuously write to subprocess using popen in C++在 C++ 中使用 popen 连续写入子进程
【发布时间】:2015-05-25 02:40:09
【问题描述】:

我需要使用 popen 打开一个子进程,该进程将不断要求用户输入...主进程需要通过管道发送该数据。

这是我的第一次尝试:

FILE *in;
char buff[1024];

if(!(in = popen("cd FIX/fix2/src; java -cp .:./* com.fix.bot", "w"))){
    return 1;
}

while(1){
    char buffer[] = { 'x' };
    fwrite(buffer, sizeof(char), sizeof(buffer), in);

    cout << "Wrote!" << endl;
    usleep(1000000);
}

但是数据没有发送!我需要用 pclose() 关闭管道,以便将数据写入进程。如何确保写入数据而不必每次都关闭管道?

【问题讨论】:

  • 您的应用是否可能正在寻找以 \n 结尾的输入?因为你现在没有发送 LF...
  • 别忘了检查fwrite() 的结果,我认为它并不能保证写出你所要求的一切。通常可以,但您需要验证。

标签: c++ ipc popen


【解决方案1】:

您需要调用fflush(in) 以确保缓冲数据实际写入流中。

还要检查命令中的java -cp .:./* 是否没有扩展到无效的类路径。如果当前目录中有多个文件,而不是实际的类路径条目,我认为最终会扩展到多个参数。

【讨论】:

  • 它仍然没有刷新...即使使用 fflush(),我仍然需要关闭管道。可能是什么问题?
  • 我更新了答案,我认为也可能是类路径设置错误。试试echo java -cp .:./* 看看它是否合法。
  • 我会确保检查命令以打开 java 进程......但到目前为止它似乎工作正常。当我关闭它时,数据被写入管道,Java 进程会做出相应的响应。但我需要确保数据已刷新....
  • 手册页中的另一条注释:“由于打开用于读取的命令的标准输入与调用 popen() 的进程共享其查找偏移量,如果原始进程已完成缓冲读取,则命令的输入位置可能与预期不同。同样,打开写入的命令的输出可能会与原始进程的输出混合。后者可以通过在 popen() 之前调用 fflush(3) 来避免。"
  • @LuisCruz:那么你的问题在于读者,而不是作者。 fflush 肯定会将字节写入管道。关闭管道唯一要做的就是发送 EOF。您需要展示您的阅读端源代码并将其更改为 Java 问题。
【解决方案2】:

这对我有用:

#include <stdio.h>
#include <unistd.h>
#include <iostream>

int main(int argc, char ** argv) {
   FILE *in;
   char buff[1024];

   if(!(in = popen("./2.sh", "w"))){
       return 1;
   }

   while(1) {
      char buffer[] = "xx\n";
      fwrite(buffer, sizeof(char), sizeof(buffer), in);
      fflush(in);
      std::cout << "Wrote!" << std::endl;
      usleep(1000000);
   }
}

2.sh 在哪里:

#!/bin/sh

read INP
echo 'read: ' $INP

所以我真的怀疑问题丢失了\n。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 2016-04-29
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    相关资源
    最近更新 更多