qt子进程和父进程读写数据通信

进程A(例如主程序)创建了一个QProcess B,这个B就称为A的子进程,而A称为B的父进程。

这也称为进程间通信,有多种方式:

  1. TCP/IP
  2. Local Server/Socket
  3. 共享内存
  4. D-Bus (Unix库)
  5. QProcess
  6. 会话管理

这里,因为是采用 QProcess创建的子进程,所以,接下来讲解的是该通信方式。

关于父进程读写子进程的数据,主要是用到:

子进程接收到了父进程数据,两个信号会发射出来:
void readyReadStandardError()
void readyReadStandardOutput()

两个功能函数:
QByteArray QProcess::readAllStandardError()
QByteArray QProcess::readAllStandardOutput()

QProcess::write()发出信息

qt子进程和父进程读写数据通信_第1张图片

这个资料就太多了,可以读我下面博客:

关于QProcess的使用问题解释_我是标同学的博客-CSDN博客

qt qprocess获取控制台输出(注意踩坑)_qprocess获取输出_我是标同学的博客-CSDN博客

QProcess用cmd运行其它进程_我是标同学的博客-CSDN博客

QT打开外部程序并嵌入Qt子窗口的缺点_qt嵌入外部窗口_我是标同学的博客-CSDN博客

qt启动cmd再启动一个exe_qt调用可执行程序exe_我是标同学的博客-CSDN博客

关于子进程读写父进程的数据,主要是用到:

  • Windows中:需要开启一个线程来管理stdin的文件变化,这个需要使用Windows API函数
  • linux中:使用QSocketNotifier 监听 stdin文件,当改文件有变化是,读取信息

windows平台:采用win的api,阻塞式的读取:

ReadFile(hStdinDup,chbuf,sizeof(chbuf),&dwRead,NULL);//读取hstdinDup句柄文件中的数据

这个是阻塞函数,类似控制台程序中的cin >> data,或者gets()。

因此需要开启一个线程来管理stdin的文件变化(函数中有涉及到while阻塞,一直检测标准输入通道stdin是否有可读取的信息,因此另开线程),在pro文件中添加:QT +=concurrent实例代码如下:

QFuture fu=QtConcurrent::run(this,&Widget::readStdin);//开启一个线程

void Widget::readStdin()//读取数据
{
    bool ok=true;
    char chbuf[1024];//缓存
    DWORD dwRead;//32位无符号整数
    HANDLE hStdinDup;//HANDLE 句柄类型
 
    const HANDLE hStdin=GetStdHandle(STD_INPUT_HANDLE);//GetStdHandle获取标准输入的句柄
    if(hStdin==INVALID_HANDLE_VALUE)//为无效句柄的话
        return;
    DuplicateHandle(GetCurrentProcess(),hStdin,
                    GetCurrentProcess(),&hStdinDup,0,false,DUPLICATE_SAME_ACCESS);//创建一个新句柄
    CloseHandle(hStdin);//关闭旧句柄
    while(ok)
    {
        ok=ReadFile(hStdinDup,chbuf,sizeof(chbuf),&dwRead,NULL);//读取hstdinDup句柄文件中的数据
        emit sig_log(QLatin1String("ok is:")+QString::number(ok));
        if(ok &&dwRead!=0)
        {
            emit sig_receivedCommand(QString::fromUtf8(chbuf,dwRead));//读取数据
        }
    }
 
}

linux平台:QFile来读取标准输入

QProcess子进程通过QFile来读取标准输入来接收父进程信息。通过QFile绑定QSocketNotifier来接收标准输入的实时信号,因为QSocketNotifier的activated信号可以通过标准输入是否有消息实时触发。

QProcess子进程通过QFile绑定标准输出stdout来发送消息给父进程。
注意:子进程读取信息不能通过QFile的readline等接口读取父进程信息,因为QFile他会读取标准输入的所有信息,并且不到长度就没有返回。哪怕QFile设置了读取长度,也会在满足长度后才有消息返回,我也不知为啥会这样。所有需要通过unstd.h的read接口来读取标准输入(Linux中才有的函数)。

    m_file.open(stdin, QFile::ReadOnly); //stdin=0
    if (m_file.isOpen())
    {
        m_clientsocket = new QSocketNotifier(m_file.handle(), QSocketNotifier::Read,this);
        connect(m_clientsocket,SIGNAL(activated(int)),this,SLOT(slotreaddata(int)));
    }

void MainWindow::slotreaddata(int fd)
{
    if(fd != m_file.handle() )
    return;

    char buf[128] = {0};
    read(fd,buf,sizeof(buf));     //不建议使用m_file.readLine(5)来读取返回值,而是unistd.h的read接口来读取标准输入(Linux中才有的函数)。
    m_readedit->append(QString::fromUtf8("接收消息:%1").arg(buf));

}
 

参考博客:

Qt 进程间通信_qt进程间通信_旷工锁的博客-CSDN博客

qt使用QProcess实现进程通信_qprocess父子进程_金色熊族的博客-CSDN博客

你可能感兴趣的:(qt,开发语言,进程间通信)