用QProcess实现父子进程的双向交互
来源:互联网 发布:淘宝买aj最靠谱的店铺 编辑:程序博客网 时间:2024/06/05 17:10
记得以前写过Linux的C程序, 里面用popen打开一个子进程, 这样可以用read/write和子进程通讯, 而在子进程里则是通过从stdin读和向stdout写实现对父进程的通讯。 QProcess的底层实现用的是类似的理念。 QProcess类提供的API让父进程可以轻松地读取子进程stdout的数据, 也可以轻松地向子进程的stdin写数据。 不过这其中还是会有各种各样颇让人费解的谜团, 需要memo一下。
Test Case
两个小程序, 父进程程序名为server。 其中定义了一个QProcess, 将QProcess的readyRead信号连接到一个槽函数上, 用来接收client端stdout上的信息。 在按下“Send to Client”按钮时调用QProcess::write发送编辑框里的文字。
子进程名为client, 定义一个QFile打开stdin, 连接readyRead信号等待server端写入的数据。 按下“Send message”时向stdout写入数据。
大家觉得这个test case能如我们预料那样正常运行吗?
问题分析
这个程序从结构上来看非常简单, 如果代码不乱写不像是会出问题的样子。 实际运行的结果还是颇让人意外的, 从client端向server端发送数据很正常, 但在client里始终收不到readyRead信号! 双向交流变成了单向, 这可真让人郁闷。 仔细看QFile的文档包括QIODevice有关的描述, 看不出问题所在。 不得已只好求助专家拉, 按照专家的意见, QFile是不支持readyRead信号的。 这一点比较好理解。 但是似乎没有什么好的Qt API可以解决此问题。
Qt的API设计里没有包括最底层设备处理的类, 这个问题经常看到有人埋怨, 比如串口通讯等功能就没有直接的Qt类可用。 不过嘛笔者觉得这个不算什么问题, 像这种特别底层的东西API超简单, open->ioctl->read/write->close就完事,就算拿Qt包一层也不会更简单 , 何必多此一举呢, 如果什么功能都依赖Qt实现, 那要我们这些程序员干啥用?!
这里就需要把原来用QFile来操作stdin的代码修改成直接open/read/write/close的方式。 如果要保持原来的“有事件才动作”也不是难事, 这部分可以用Qt里的QSocketNotifier类监控fd的读写事件, 在收到信号时才去调用read/write。
主要代码
server端开进程
if(! pro )
{
pro = new QProcess(this);
connect(pro, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int, QProcess::ExitStatus)));
connect(pro, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
connect(pro, SIGNAL(readyRead()), this, SLOT(readFromClient()));
pro->start(“./client”);
}
server端接收数据
void MainWin::readFromClient()
{
if( !pro) return;
QByteArray output = pro->readAllStandardOutput();
qWarning() }
server端发送数据
void MainWin::writeToClient()
{
if( !pro) return;
pro->write(le->text().toLatin1().constData(), le->text().length());
qWarning() text();
}
client端监控stdin的读写消息
filein.open(stdin, QIODevice::ReadOnly);
QSocketNotifier* sn = new QSocketNotifier(filein.handle(), QSocketNotifier::Read, this);
connect(sn, SIGNAL(activated(int)), this, SLOT(readFromServer(int)));
client端接收数据
void MainWin::readFromServer(int fd)
{
if(fd != filein.handle() )
return;char buffer[256];
int count = read(filein.handle(), buffer, 256);
le->setText(“FROM SERVER:” + QString(buffer).left(count));
}
client端发送数据
void MainWin::writeToServer()
{
QFile fileout;
fileout.open(stdout, QIODevice::WriteOnly);
fileout.write(le->text().toLatin1().constData(), le->text().length()); // write to stderr
qWarning() text();
fileout.close();
}
主要代码列出来,例子就不贴附件了。
from: http://blog.chinaunix.net/uid-13830775-id-97752.html
- 用QProcess实现父子进程的双向交互
- windows父子进程交互的一个例子
- 父子进程信号交互
- 父子进程的双向通讯简明解读(c程序)。
- 寻根1:unix/linux下的父子进程交互
- vue2实现父子组件的数据双向绑定
- html父子页面(弹框)的实现和交互[通信]
- qt进程间的通行 QProcess
- 信号实现父子进程同步
- 信号实现父子进程之间的同步--sigsuspend的作用
- 信号实现父子进程之间的同步--sigsuspend的作用
- 信号实现父子进程之间的同步--sigsuspend的作用
- linux多线程【8】mmap实现父子进程的共享内存通信,用信号量同步
- 无名管道及用其实现父子进程间的通信
- 利用共享存储实现父子进程间的通信
- 应用管道实现父子进程之间的通信
- 匿名管道实现父子进程之间的通信....
- 应用管道实现父子进程之间的通信
- 读取web.xml文件中数据的三种方法
- R语言入门
- ARM汇编编程规则
- 数据库表设计时一对一关系
- 如何将数据绑定到gridview指定列中,终于解决啦~
- 用QProcess实现父子进程的双向交互
- 使用ZooKeeper实现配置同步
- QT中使用QProcess启用外部程序和关闭外部程序
- 欢迎使用CSDN-markdown编辑器
- C++ Primer中文版(第5版)——互动出版网
- android studio 在release打包时修改AndroidManifest.xml
- elk+redis 搭建日志分析平台
- Ubuntu or Deepin 上安装 mysql 数据库
- RecyclerView的拖动和滑动 第二部分 :拖块,Grid以及自定义动画