QT--进程

一、进程QProcess

QProcess 用于启动和控制外部进程,管理其输入输出流。

  1. 使用方法
  • start():启动一个新进程。
  • setStandardInputFile():将文件作为标准输入。将进程的标准输入(stdin)重定向到指定的文件。换句话说,进程会从这个文件中读取输入数据,而不是从命令行或其他输入源读取。
  • setStandardOutputFile():将文件作为标准输出。也就是说,进程的所有输出数据(正常输出)将被写入这个文件,而不是显示在控制台或其他标准输出流。
  • readAllStandardOutput():读取所有标准输出数据。
  • terminate():终止进程。
  • kill():杀死进程。
  • waitForStarted():等待进程启动完成。
  • write():向进程的标准输入写数据。
  • waitForFinished():等待进程结束。
  • state():获取进程的当前状态。
  1. 信号
  • started()
    当使用QProcess::start()成功启动进程(连锁触发)时,QProcess对象会发射started()信号。这意味着被启动的进程已经成功运行。
  • finished()
    当进程(触发的进程)完成并退出时发射。可用于处理进程完成后的清理工作。
  • stateChanged()
    当进程状态发生变化时,会触发这个信号。通过newState可以知道进程当前的状态。
    QProcess::NotRunning:进程未运行。
    QProcess::Starting:进程正在启动。
    QProcess::Running:进程正在运行。
  • readyReadStandardOutput()
    readyReadStandardOutput() 是 QProcess 类的一个信号,当外部进程的标准输出有数据可读时发射。可以使用这个信号来读取外部进程的输出数据。

QSharedMemory 用于在进程间共享数据,创建和管理共享内存。

  1. 包含头文件QSharedMemory
  2. 创建QSharedMemory对象。并指定共享内存的名字。共享内存的名称是一个唯一标识符,确保不同进程能够正确地访问相同的共享内存区域。
c 复制代码
QSharedMemory sharedMemory("MySharedMemory");
等价于
QSharedMemory sharedMemory;
sharedMemory->setKey("MySharedMemory");
  1. 创建共享内存
cpp 复制代码
if (!sharedMemory->create(1024)) { // 创建1024字节的共享内存
    qDebug() << "Failed to create shared memory";
}
  1. 链接到共享内存:在另一个进程中,尝试连接到已存在的共享内存区域
cpp 复制代码
pShareM = new QSharedMemory;
pShareM->setKey("MySharedMemory");//设置同一个共享内存区域
if (!pShareM->attach()) {// 连接到共享内存
    qDebug() << "Failed to attach to shared memory";
}
  1. 锁定共享内存以读写数据
cpp 复制代码
//写入数据
if (sharedMemory.lock()) {
    char *to = static_cast<char *>(sharedMemory.data());
    strcpy(to, "Hello from Qt!");//关键代码
    sharedMemory.unlock();
} else {
    qDebug() << "Failed to lock shared memory for writing";
}
//读取数据
if (sharedMemory.lock()) {
    char *from = static_cast<char *>(sharedMemory.data());
    qDebug() << "Data from shared memory:" << from;//关键代码
    sharedMemory.unlock();
} else {
    qDebug() << "Failed to lock shared memory for reading";
}
  1. 解除链接和删除共享内存
cpp 复制代码
sharedMemory.detach();
sharedMemory.destroy();

代码示例

cpp 复制代码
//主进程
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QProcess>
#include <QSharedMemory>
#include <QFile>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 初始化 QProcess 对象,并连接信号到槽
    pSubP = new QProcess(this);
    connect(pSubP, SIGNAL(started()), this, SLOT(pSubStartedSlotFun()));  // 当子进程启动时
    connect(pSubP, SIGNAL(finished(int)), this, SLOT(pSubPFinishedSlotFun(int)));  // 当子进程完成时
    connect(pSubP, SIGNAL(readyReadStandardOutput()), this, SLOT(readSubPOutput()));  // 子进程有标准输出数据时

    // 启动子进程,并指定子进程的执行程序路径
    pSubP->start("/mnt/hgfs/linux_learn/qt_file/process/sub/build-project7_24_vice_process-Desktop_Qt_5_12_9_GCC_64bit-Debug/project7_24_vice_process");

    // 设置子进程的标准输入和标准输出文件
    pSubP->setStandardInputFile("/path/to/input.txt");  // 设置标准输入来源为指定文件
    pSubP->setStandardOutputFile("/path/to/output.txt");  // 设置标准输出目的地为指定文件

    // 初始化共享内存
    pShareM = new QSharedMemory(this);
    pShareM->setKey("zhhhhhhhhhhhhhhz");  // 设置共享内存的唯一标识符

    // 创建共享内存,大小为128字节
    if (!pShareM->create(128)) {
        qDebug() << "Failed to create shared memory";  // 创建失败时输出调试信息
    } else {
        qDebug() << "Shared memory created";  // 创建成功时输出调试信息
    }

    // 连接按钮点击信号到槽函数
    connect(ui->btnWrite, SIGNAL(clicked()), this, SLOT(btnWriteClickedSlotFun()));  // 当点击写入按钮时
    connect(ui->btnRead, SIGNAL(clicked()), this, SLOT(btnReadClickedSlotFun()));  // 当点击读取按钮时
    connect(ui->btnTerminate, SIGNAL(clicked()), this, SLOT(btnTerminateClickedSlotFun()));  // 当点击终止按钮时
    connect(ui->btnKill, SIGNAL(clicked()), this, SLOT(btnKillClickedSlotFun()));  // 当点击杀死按钮时
}

Widget::~Widget()
{
    delete ui;
    // 解除共享内存的连接
    if (pShareM->isAttached()) {
        pShareM->detach();
    }
}

void Widget::pSubStartedSlotFun()
{
    qDebug() << "Sub process started";  // 子进程启动时输出调试信息
}

void Widget::pSubPFinishedSlotFun(int exitCode)
{
    qDebug() << "Sub process finished with exit code:" << exitCode;  // 子进程结束时输出调试信息,包含退出码
}

void Widget::readSubPOutput()
{
    // 读取子进程的标准输出
    QByteArray output = pSubP->readAllStandardOutput();
    qDebug() << "Output from sub process:" << output;  // 输出子进程的标准输出数据
}

void Widget::btnWriteClickedSlotFun()
{
    // 获取文本框中的文本
    QString str = ui->textEdit->toPlainText();
    std::string sstr = str.toStdString();
    const char *p = sstr.c_str();

    // 写入数据到共享内存
    if (pShareM->lock()) {  // 锁定共享内存以确保数据安全写入
        memcpy(pShareM->data(), p, sstr.length());  // 复制数据到共享内存
        pShareM->unlock();  // 解锁共享内存
        qDebug() << "Data written to shared memory";  // 输出写入数据成功的调试信息
    } else {
        qDebug() << "Failed to lock shared memory for writing";  // 锁定共享内存失败时输出调试信息
    }
}

void Widget::btnReadClickedSlotFun()
{
    // 从共享内存中读取数据
    if (pShareM->lock()) {  // 锁定共享内存以确保数据安全读取
        char *from = static_cast<char *>(pShareM->data());  // 获取共享内存的数据指针
        ui->textEdit->setText(from);  // 将读取到的数据设置到文本框中
        pShareM->unlock();  // 解锁共享内存
        qDebug() << "Data read from shared memory";  // 输出读取数据成功的调试信息
    } else {
        qDebug() << "Failed to lock shared memory for reading";  // 锁定共享内存失败时输出调试信息
    }
}

void Widget::btnTerminateClickedSlotFun()
{
    pSubP->terminate();  // 请求子进程正常终止
    pSubP->waitForFinished();  // 等待子进程终止
    qDebug() << "Sub process terminated";  // 输出子进程终止的调试信息
}

void Widget::btnKillClickedSlotFun()
{
    pSubP->kill();  // 强制杀死子进程
    pSubP->waitForFinished();  // 等待子进程结束
    qDebug() << "Sub process killed";  // 输出子进程被杀死的调试信息
}
//被启动进程的代码
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QSharedMemory>
#include <QFile>
#include <QTextStream>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 初始化共享内存
    pShareM = new QSharedMemory(this);
    pShareM->setKey("zhhhhhhhhhhhhhhz");  // 设置共享内存的唯一标识符

    // 尝试连接到共享内存
    if (!pShareM->attach()) {  // 连接到已经存在的共享内存
        qDebug() << "Failed to attach to shared memory";  // 连接失败时输出调试信息
    } else {
        qDebug() << "Attached to shared memory";  // 连接成功时输出调试信息
    }

    // 连接按钮点击信号到槽函数
    connect(ui->btnRead, SIGNAL(clicked()), this, SLOT(btnReadClickedSlotFun()));  // 当点击读取按钮时
    connect(ui->btnWrite, SIGNAL(clicked()), this, SLOT(btnWriteClickedSlotFun()));  // 当点击写入按钮时
}

Widget::~Widget()
{
    delete ui;
    // 解除共享内存的连接
    if (pShareM->isAttached()) {
        pShareM->detach();
    }
}

void Widget::btnReadClickedSlotFun()
{
    // 从共享内存中读取数据
    if (pShareM->lock()) {  // 锁定共享内存以确保数据安全读取
        char *from = static_cast<char *>(pShareM->data());  // 获取共享内存的数据指针
        ui->textEdit->setText(from);  // 将读取到的数据设置到文本框中
        pShareM->unlock();  // 解锁共享内存
        qDebug() << "Data read from shared memory";  // 输出读取数据成功的调试信息
    } else {
        qDebug() << "Failed to lock shared memory for reading";  // 锁定共享内存失败时输出调试信息
    }
}

void Widget::btnWriteClickedSlotFun()
{
    // 获取文本框中的文本
    QString str = ui->textEdit->toPlainText();
    std::string sstr = str.toStdString();
    const char *p = sstr.c_str();

    // 写入数据到共享内存
    if (pShareM->lock()) {  // 锁定共享内存以确保数据安全写入
        memcpy(pShareM->data(), p, sstr.length());  // 复制数据到共享内存
        pShareM->unlock();  // 解锁共享内存
        qDebug() << "Data written to shared memory";  // 输出写入数据成功的调试信息
    } else {
        qDebug() << "Failed to lock shared memory for writing";  // 锁定共享内存失败时输出调试信息
    }
}

代码存放路径

运行

相关推荐
用户805533698032 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner2 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz7 天前
QML Hello World 入门示例
qt
xcyxiner10 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner11 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner11 天前
DicomViewer (添加模型类)3
qt
xcyxiner12 天前
DicomViewer (目录调整) 2
qt
xcyxiner12 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00614 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术14 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript