亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

QT使用共享內(nèi)存實(shí)現(xiàn)進(jìn)程間通訊

 更新時(shí)間:2024年12月13日 09:17:22   作者:hss2799  
這篇文章主要為大家詳細(xì)介紹了QT如何使用共享內(nèi)存實(shí)現(xiàn)進(jìn)程間通訊,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

QSharedMemory:如果兩個(gè)進(jìn)程運(yùn)行在同一臺(tái)機(jī)器上,且對(duì)性能要求非常高(如實(shí)時(shí)數(shù)據(jù)共享、圖像渲染等),建議使用共享內(nèi)存。

優(yōu)點(diǎn):

  • 高性能: 共享內(nèi)存是進(jìn)程間通信的最快方式之一,因?yàn)閿?shù)據(jù)直接在內(nèi)存中共享,不需要經(jīng)過(guò)內(nèi)核的系統(tǒng)調(diào)用或網(wǎng)絡(luò)協(xié)議棧。
  • 低延遲: 由于數(shù)據(jù)直接在內(nèi)存中傳遞,延遲非常低,適合需要高性能的場(chǎng)景(如實(shí)時(shí)數(shù)據(jù)處理、圖像渲染等)。
  • 簡(jiǎn)單數(shù)據(jù)共享: 適合兩個(gè)進(jìn)程需要頻繁訪(fǎng)問(wèn)相同數(shù)據(jù)的場(chǎng)景。

設(shè)計(jì)思路

共享內(nèi)存區(qū):用于存儲(chǔ)數(shù)據(jù)。

互斥量:用于保護(hù)共享內(nèi)存區(qū),防止多個(gè)進(jìn)程同時(shí)訪(fǎng)問(wèn)導(dǎo)致數(shù)據(jù)不一致。

信號(hào)量:用于通知對(duì)方有數(shù)據(jù)可用。

服務(wù)器實(shí)現(xiàn)

頭文件

#ifndef SHAREDMEMORYSERVICE_H
#define SHAREDMEMORYSERVICE_H

#include <QObject>
#include <QSharedMemory>
#include <QBuffer>
#include <QDataStream>
#include <QDebug>
#include <QThread>
#include <QSystemSemaphore>

class SharedMemoryService : public QObject
{
    Q_OBJECT
public:
    explicit SharedMemoryService(QObject* parent = nullptr);
    ~SharedMemoryService();

    // 向共享內(nèi)存中寫(xiě)入數(shù)據(jù)
    bool writeToSharedMemory(const QByteArray& data);

signals:
    // 當(dāng)讀取到共享內(nèi)存中的數(shù)據(jù)時(shí)發(fā)出信號(hào)
    void signalRead(QBuffer& buffer);

private slots:
    // 檢查共享內(nèi)存中的數(shù)據(jù)
    void checkSharedMemory();

private:
    std::shared_ptr<QSharedMemory> m_sharedMemory; // 共享內(nèi)存
    std::shared_ptr<QSystemSemaphore> m_semaphoreClient; // 信號(hào)量 - 客戶(hù)端發(fā)送
    std::shared_ptr<QSystemSemaphore> m_semaphoreService; // 信號(hào)量- 服務(wù)器發(fā)送
    bool m_bCreate = false;                        // 是否創(chuàng)建成功
    bool m_bExit = false;                        // 是否退出
    QThread m_listenThread;                        // 監(jiān)聽(tīng)線(xiàn)程
};

#endif // SHAREDMEMORYSERVICE_H

cpp

#include "SharedMemoryService.h"

SharedMemoryService::SharedMemoryService(QObject* parent)
    : QObject(parent),
    m_sharedMemory(std::make_shared<QSharedMemory>("MySharedMemoryKey_XXX")),
    m_semaphoreClient(std::make_shared<QSystemSemaphore>("MySemaphoreKey_XXX", 0)),
    m_semaphoreService(std::make_shared<QSystemSemaphore>("MySemaphoreKey_XXX2", 0))
{
    // 創(chuàng)建共享內(nèi)存,大小為1024字節(jié)
    if (!m_sharedMemory->create(1024)) {
        qDebug() << "無(wú)法創(chuàng)建共享內(nèi)存:" << m_sharedMemory->errorString();
        return;
    }
    m_bCreate = true;

    // 移動(dòng)監(jiān)聽(tīng)線(xiàn)程到單獨(dú)的線(xiàn)程中
    QObject::connect(&m_listenThread, &QThread::started, this, &SharedMemoryService::checkSharedMemory, Qt::DirectConnection);
    m_listenThread.start();
}

SharedMemoryService::~SharedMemoryService()
{
    m_bExit = true;
    m_semaphoreClient->release(1);
    // 停止監(jiān)聽(tīng)線(xiàn)程
    m_listenThread.quit();
    m_listenThread.wait();
}

void SharedMemoryService::checkSharedMemory()
{
    if (!m_bCreate || !m_sharedMemory->isAttached())
        return;

    while (true)
    {
        // 等待信號(hào)量
        if (m_semaphoreClient->acquire()) 
        {
            if (m_bExit)
            {
                break;
            }
            if (m_sharedMemory->lock()) 
            {
                // 讀取共享內(nèi)存中的數(shù)據(jù)
                QBuffer buffer;
                buffer.setData((char*)m_sharedMemory->data(), m_sharedMemory->size());
                buffer.open(QIODevice::ReadOnly);

                // 如果共享內(nèi)存中有數(shù)據(jù),則發(fā)出信號(hào)
                if (buffer.size() > 0) {
                    emit signalRead(buffer);

                    // 清空共享內(nèi)存內(nèi)容
                    memset(m_sharedMemory->data(), 0, m_sharedMemory->size());
                }

                // 解鎖共享內(nèi)存
                m_sharedMemory->unlock();
            }
        }
    }
}

bool SharedMemoryService::writeToSharedMemory(const QByteArray& data)
{
    if (!m_bCreate || !m_sharedMemory->isAttached())
    {
        qDebug() << "共享內(nèi)存未創(chuàng)建或未附加";
        return false;
    }

    if (m_sharedMemory->lock()) {
        // 將數(shù)據(jù)寫(xiě)入共享內(nèi)存
        memcpy(m_sharedMemory->data(), data.data(), qMin(data.size(), m_sharedMemory->size()));

        // 釋放鎖
        m_sharedMemory->unlock();

        // 增加信號(hào)量計(jì)數(shù),通知監(jiān)聽(tīng)線(xiàn)程有數(shù)據(jù)可用
        m_semaphoreService->release(1);

        return true;
    }

    qDebug() << "無(wú)法鎖定共享內(nèi)存";
    return false;
}

調(diào)用

/// 創(chuàng)建共享內(nèi)存
void MainWindow::slotCrateBtn()
{
    if (m_service)
    {
        return;
    }
    ui->btnCreate->setEnabled(false);
    m_service = new SharedMemoryService();
    // 連接信號(hào)槽,監(jiān)聽(tīng)共享內(nèi)存中的數(shù)據(jù)
    QObject::connect(m_service, &SharedMemoryService::signalRead, this, &MainWindow::slotRecv, Qt::DirectConnection);
}

/// 發(fā)送內(nèi)容
void MainWindow::slotSendBtn()
{
    if (m_service == nullptr)
    {
        return;
    }    
    // 向共享內(nèi)存中寫(xiě)入數(shù)據(jù)
    QByteArray data = ui->textEditSend->toPlainText().toLocal8Bit();
    if (m_service->writeToSharedMemory(data))
    {
        qDebug() << "數(shù)據(jù)已成功寫(xiě)入共享內(nèi)存";
    }
    else
    {
        qDebug() << "寫(xiě)入共享內(nèi)存失敗";
    }
}

/// 收到數(shù)據(jù)
void MainWindow::slotRecv(QBuffer& buffer)
{
    QString text = buffer.data();
    if (text.isEmpty())
    {
        return;
    }
    qDebug() << "接收到共享內(nèi)存中的數(shù)據(jù):" << text;
    ui->textEdit->append(text);
}

客戶(hù)端實(shí)現(xiàn)

頭文件

#ifndef SHAREDMEMORYCLIENT_H
#define SHAREDMEMORYCLIENT_H

#include <QObject>
#include <QSharedMemory>
#include <QBuffer>
#include <QDataStream>
#include <QDebug>
#include <QThread>
#include <QSystemSemaphore>

#include <cstdio>
#include <iostream>
#include <list>
#include <memory>
#include <string>

class SharedMemoryClient : public QObject
{
    Q_OBJECT
public:
    explicit SharedMemoryClient(QObject* parent = nullptr);

    ~SharedMemoryClient();

    // 向共享內(nèi)存中寫(xiě)入數(shù)據(jù)
    bool writeToSharedMemory(const QByteArray& data);

signals:
    // 當(dāng)讀取到共享內(nèi)存中的數(shù)據(jù)時(shí)發(fā)出信號(hào)
    void signalRead(QBuffer& buffer);

private slots:
    // 處理共享內(nèi)存中的數(shù)據(jù)
    void processSharedMemory();

private:
    std::shared_ptr<QSharedMemory> m_sharedMemory; // 共享內(nèi)存
    std::shared_ptr<QSystemSemaphore> m_semaphoreClient; // 信號(hào)量 - 客戶(hù)端發(fā)送
    std::shared_ptr<QSystemSemaphore> m_semaphoreService; // 信號(hào)量- 服務(wù)器發(fā)送
    bool m_bCreate = false;                        // 是否創(chuàng)建成功
    bool m_bExit = false;                        // 是否退出
    QThread m_listenThread;                        // 監(jiān)聽(tīng)線(xiàn)程
};

#endif // SHAREDMEMORYCLIENT_H

cpp

#include "SharedMemoryClient.h"

SharedMemoryClient::SharedMemoryClient(QObject* parent)
    : QObject(parent), m_sharedMemory(std::make_shared<QSharedMemory>("MySharedMemoryKey_XXX")),
    m_semaphoreClient(std::make_shared<QSystemSemaphore>("MySemaphoreKey_XXX", 0)),
    m_semaphoreService(std::make_shared<QSystemSemaphore>("MySemaphoreKey_XXX2", 0))
{
    if (!m_sharedMemory->attach()) {
        qDebug() << "無(wú)法附加到共享內(nèi)存:" << m_sharedMemory->errorString();
        return;
    }
    m_bCreate = true;

    // 將處理方法移動(dòng)到監(jiān)聽(tīng)線(xiàn)程中
    moveToThread(&m_listenThread);
    connect(&m_listenThread, &QThread::started, this, &SharedMemoryClient::processSharedMemory, Qt::DirectConnection);

    // 啟動(dòng)監(jiān)聽(tīng)線(xiàn)程
    m_listenThread.start();
}

SharedMemoryClient::~SharedMemoryClient()
{
    m_bExit = true;
    m_semaphoreService->release(1);
    // 停止監(jiān)聽(tīng)線(xiàn)程
    m_listenThread.quit();
    m_listenThread.wait();
}

void SharedMemoryClient::processSharedMemory()
{
    while (true) 
    {
        if (m_semaphoreService->acquire())
        {
            if (m_bExit)
            {
                break;
            }
            if (!m_bCreate || !m_sharedMemory->isAttached())
                continue;

            // 鎖定共享內(nèi)存
            if (m_sharedMemory->lock())
            {
                // 檢查共享內(nèi)存是否有數(shù)據(jù)
                QBuffer buffer;
                buffer.setData((char*)m_sharedMemory->data(), m_sharedMemory->size());
                buffer.open(QIODevice::ReadOnly);

                // 如果共享內(nèi)存中有數(shù)據(jù),則發(fā)出信號(hào)
                if (buffer.size() > 0)
                {
                    emit signalRead(buffer);

                    // 清空共享內(nèi)存內(nèi)容
                    memset(m_sharedMemory->data(), 0, m_sharedMemory->size());
                }

                // 解鎖共享內(nèi)存
                m_sharedMemory->unlock();
            }
        }
    }
}

bool SharedMemoryClient::writeToSharedMemory(const QByteArray& data)
{
    if (!m_bCreate || !m_sharedMemory->isAttached())
    {
        qDebug() << "共享內(nèi)存未創(chuàng)建或未附加";
        return false;
    }

    // 鎖定共享內(nèi)存
    if (m_sharedMemory->lock())
    {
        // 將數(shù)據(jù)寫(xiě)入共享內(nèi)存
        memcpy(m_sharedMemory->data(), data.data(), qMin(data.size(), m_sharedMemory->size()));

        // 解鎖共享內(nèi)存
        m_sharedMemory->unlock();

        // 釋放信號(hào)量,通知監(jiān)聽(tīng)線(xiàn)程
        m_semaphoreClient->release(1);

        return true;
    }

    qDebug() << "無(wú)法鎖定共享內(nèi)存";
    return false;
}

調(diào)用

/// 連接共享內(nèi)存
void MainWindow::slotCrateBtn()
{
    if (m_client)
    {
        return;
    }
    ui->btnCreate->setEnabled(false);
    m_client = new SharedMemoryClient();
    // 連接信號(hào)槽,監(jiān)聽(tīng)共享內(nèi)存中的數(shù)據(jù)
    QObject::connect(m_client, &SharedMemoryClient::signalRead, this, &MainWindow::slotRecv, Qt::DirectConnection);


}

/// 發(fā)送內(nèi)容
void MainWindow::slotSendBtn()
{
    if (m_client == nullptr)
    {
        return;
    }
    // 向共享內(nèi)存中寫(xiě)入數(shù)據(jù)
    QByteArray data = ui->textEditSend->toPlainText().toLocal8Bit();
    if (m_client->writeToSharedMemory(data))
    {
        qDebug() << "數(shù)據(jù)已成功寫(xiě)入共享內(nèi)存";
    }
    else
    {
        qDebug() << "寫(xiě)入共享內(nèi)存失敗";
    }
}
/// 收到數(shù)據(jù)
void MainWindow::slotRecv(QBuffer& buffer)
{
    QString text = buffer.data();
    if (text.isEmpty())
    {
        return;
    }
    qDebug() << "接收到共享內(nèi)存中的數(shù)據(jù):" << text;
    ui->textEdit->append(text);
}

運(yùn)行效果

以上就是QT使用共享內(nèi)存實(shí)現(xiàn)進(jìn)程間通訊的詳細(xì)內(nèi)容,更多關(guān)于QT進(jìn)程間通訊的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語(yǔ)言泛型選擇編程示例詳解

    C語(yǔ)言泛型選擇編程示例詳解

    這篇文章主要介紹了C語(yǔ)言泛型選擇編程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • 總結(jié)UNIX/LINUX下C++程序計(jì)時(shí)的方法

    總結(jié)UNIX/LINUX下C++程序計(jì)時(shí)的方法

    本文總結(jié)了下UNIX/LINUX下C++程序計(jì)時(shí)的一些函數(shù)和方法,對(duì)日常使用C++程序的朋友很有幫助,有需要的小伙伴們可以參考學(xué)習(xí),下面一起來(lái)看看吧。
    2016-08-08
  • C++ 中繼承與動(dòng)態(tài)內(nèi)存分配的詳解

    C++ 中繼承與動(dòng)態(tài)內(nèi)存分配的詳解

    這篇文章主要介紹了C++ 中繼承與動(dòng)態(tài)內(nèi)存分配的詳解的相關(guān)資料,這里提供實(shí)例幫助大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下
    2017-08-08
  • 利用反射獲得類(lèi)的public static/const成員的值實(shí)例

    利用反射獲得類(lèi)的public static/const成員的值實(shí)例

    下面小編就為大家?guī)?lái)一篇利用反射獲得類(lèi)的public static/const成員的值實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • Qt設(shè)計(jì)時(shí)鐘效果

    Qt設(shè)計(jì)時(shí)鐘效果

    這篇文章主要為大家詳細(xì)介紹了Qt設(shè)計(jì)時(shí)鐘效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • c++代碼各種注釋示例詳解

    c++代碼各種注釋示例詳解

    大家好,本篇文章主要講的是c++代碼各種注釋示例詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話(huà)記得收藏一下,方便下次瀏覽
    2021-12-12
  • C++小知識(shí):復(fù)制粘貼代碼千萬(wàn)要小心

    C++小知識(shí):復(fù)制粘貼代碼千萬(wàn)要小心

    今天小編就為大家分享一篇關(guān)于C++小知識(shí):復(fù)制粘貼代碼千萬(wàn)要小心,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • C++?vector的常見(jiàn)用法超詳細(xì)講解

    C++?vector的常見(jiàn)用法超詳細(xì)講解

    這篇文章主要介紹了C++?vector的常見(jiàn)用法,包括C++中vector容器的定義、初始化方法、訪(fǎng)問(wèn)元素、常用函數(shù)及其時(shí)間復(fù)雜度,通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-04-04
  • 詳解C++11 線(xiàn)程休眠函數(shù)

    詳解C++11 線(xiàn)程休眠函數(shù)

    這篇文章主要介紹了C++11 線(xiàn)程休眠函數(shù)的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)C++11,感興趣的朋友可以了解下
    2020-10-10
  • 淺談Windows系統(tǒng)下C語(yǔ)言編程中Glib庫(kù)的使用

    淺談Windows系統(tǒng)下C語(yǔ)言編程中Glib庫(kù)的使用

    這篇文章主要介紹了Windows系統(tǒng)下C語(yǔ)言編程中Glib庫(kù)的使用,Glib庫(kù)在多線(xiàn)程編程中經(jīng)??梢杂玫?需要的朋友可以參考下
    2016-02-02

最新評(píng)論