Linux下用C++实现子进程控制台的输入和输出
在linux下对编写的控制台程序进行测试的话,就需要对子进程的控制台输入和输出进行控制。在测试进程中,完成子进程控制台的输入和输出操作,我们通用的做法是通过父子进程建立管道,通过dup2完成管道和标准输入、输出的绑定。在父进程中通过read和write函数对管道进行读写,以下就是示例代码。
如果你想在Windows平台实现这样的功能,可以参考Windows用C++实现控制台的输入输出
1、父进程示例代码
/**
* @file SendString.cpp
* @author DennisMi (https://www.dennisthink.com/)
* @brief 调用RecvString的函数,在测试的时候作为主进程
* @version 0.1
* @date 2020-05-29
*
* @copyright Copyright (c) 2020
*
*/
#include <string>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <iostream>
int main(int argc, char *argv[]) {
int writePipe[2]={0};//Parent--->child
int readPipe[2]={0};//Child---->Parent
char buf[] = "HELLO\n";
char quitBuf[]="quit\n";
char readBuf[128]={0};
//创建管道
if(pipe(writePipe)){
std::cerr<<"Create Write Pipe Failed "<<std::endl;
return -1;
}
//创建管道
if(pipe(readPipe)){
std::cerr<<"Create Read Pipe Failed "<<std::endl;
return -1;
}
switch(fork()){
case -1:
{
perror("fork");
return -1;
}break;
case 0:
{
// 子进程
std::cout<<"Create Child Process Succeed"<<std::endl;
close(writePipe[1]);//关闭未使用的写端
close(readPipe[0]);//关闭未使用的读端
dup2(writePipe[0], STDIN_FILENO);//映射子进程的标准输入
dup2(readPipe[1],STDOUT_FILENO);//映射子进程的标准输出
int nResult = execl("/home/dennis/Code/RecvString", //子进程路径
"RecvString",//子进程名称
(char*)(0));//参数
std::cout<<"Start Child "<<nResult<<std::endl;//如果启动失败,则此信息输出
}break;
default:
{
//父进程
std::cout<<"Parent Succeed"<<std::endl;
close(writePipe[0]);//关闭未使用的读端
close(readPipe[1]);//关闭未使用的写端
sleep(5);//等待子进程启动
// parent
// 业务代码开始
//处理和子进程的交互,此处属于业务逻辑代码,需要和具体的业务结合
std::string strResult;
for(int i = 0 ; i < 100 ; i++)
{
strResult = std::to_string(i)+buf;
memset(readBuf,0,128);
read(readPipe[0],readBuf,128);//读取子进程的输出
std::cout<<"Read From Child: "<<readBuf<<std::endl;
write(writePipe[1], strResult.c_str(), strResult.length());//给子进程写数据
}
write(writePipe[1], quitBuf, sizeof(quitBuf));
memset(readBuf,0,128);
read(readPipe[0],readBuf,128);
std::cout<<"Read From Child: "<<readBuf<<std::endl;
//业务代码结束
wait(nullptr);//等待子进程结束
}break;
}
std::cout<<"Parent Process Exit"<<std::endl;
close(readPipe[0]);
close(readPipe[1]);
close(writePipe[0]);
close(writePipe[1]);
return 0;
}
2、子进程示例代码
/**
* @file RecvString.cpp
* @author DennisMi (https://www.dennisthink.com/)
* @brief 被测试的程序,输出用户输入的字符串,输入quit退出
* @version 0.1
* @date 2020-05-29
*
* @copyright Copyright (c) 2020
*
*/
#include <iostream>
#include <string>
int main(int argc,char * argv[])
{
std::string strInput;
while(true)
{
std::cout<<"Please Input Your String:"<<std::endl;
std::cin>>strInput;
std::cout<<"Your Input is: " <<strInput<<std::endl;
if("quit"==strInput)
{
std::cout<<"Exit Program"<<std::endl;
break;
}
}
return 0;
}
3、程序演示
单独调用子程序
通过父进程调用子程序