QSharedMemory介绍

2023-12-17

1. QSharedMemory介绍

QSharedMemory提供了 多个线程和进程对共享内存段的访问 。它还提供了一种方法,让单个线程或进程锁定内存以进行独占访问。

当使用这个类时,请注意以下平台差异:

  • windows: QSharedMemory不"拥有”共享内存段。当有QSharedMemory?实例附加到特定共享内存段的所有线程或进程销毁了它们的QSharedMemory3实例或者退出了,Windows内核会自动释放共享内存段。
  • Unix: QSharedMemory"拥有”共享内存段。当最后一个线程或进程将一个QSharedMemory实例附加到一个特定的共享内存段时,通过
    销毁它的QSharedMemory实例从这个段中分离出来,Unix内核释放这个共享内存段。但是如果最后一个线程或进程在没有运行QShared
    Memory析构函数的情况下崩溃了(未释放),共享内存段会在崩溃时幸存下来。

在对共享内存进行读写操作之前,记得使用ock0锁定共享内存,并且记得在操作完成后使用unlocko释放锁。

它的构造函数如下所示:

QSharedMemory (const QString &key,Qobject parent nullptr)

通过指定的parent和key,构造一个共享内存对象。由于key已经被设置,所以不需要再调用setKey0或setNativeKey(0指定要访问的内存块了,create()和attach()就可以被调用了。

其它常用函数如下所示:

QString QSharedMemory::key() const
//返回被setKey()所赋值的key如果未设置key则返回空字符串,如果应用程序是和非Qt平台的,则需要使用nativeKey()访问

bool QSharedMemory::lock()
//用来锁定共享内存的互斥值,锁住成功则返回true. 若另一个进程已经锁住了共享内存段,本函数将会阻塞直到锁被另一个进程释放。到那时,本函数才会获得锁并返回true. 如果本函数返回false,那就说明你已经忽略了一个由create()或attach()返回的false,而其原因可能是由于某个系统错误而导致setNativeKey()或QSystemSemaphore::acquire()失败。

bool QSharedMemory::unlock()
//释放共享内存段上的锁并返回true,如果共享内存段没有被lock,或者如果锁被其他进程持有,本函数什么都不会做而只是返回false. 

 
bool QSharedMemory::create(int size, AccessMode mode=ReadWrite)
//创建一个大小为size个字节的共享内存段, 然后用给定的访问模式mode附着到共享内存上。Mode取值有以下几种:
QSharedMemory::ReadOnly : 共享内存段是只读的。不允许写入共享内存段。尝试写入使用ReadOnly创建的共享内存段会导致程序中止。
QSharedMemory::ReadWrite : 允许对共享内存段进行读写操作。

bool QSharedMemory::attach(AccessMode mode = ReadWrite)
//尝试将进程附加到由传递给构造函数或调用setKey()或setNativeKey()的键标识的共享内存段上。默认访问模式为“ReadWrite”。也可以是ReadOnly。如果附加操作成功,则返回true。如果返回false,则调用error()或者errorString()来确定发生了哪个错误。在附加共享内存段成功之后,则可以通过调用data()来获得一个指向共享内存的指针。

bool QSharedMemory::isAttached() const
//如果该进程附加到共享内存段,则返回true。

bool QSharedMemory::detach()
//将进程从共享内存段中分离。如果这是连接到共享内存段的最后一个进程,那么共享内存段将被系统释放,也就是说,内容将被销毁。如果函数分离了共享内存段,则返回true。如果它返回false,通常意味着该段没有连接,或者被另一个进程锁定。

void * QSharedMemory::data()
//如果附加了共享内存段,则返回指向共享内存段内容的指针。否则返回null。在对共享内存进行读写操作之前,记得使用lock()锁定共享内存,并且记得在操作完成后使用unlock()释放锁。

2. QSharedMemory示例

以不同进程间共享内存为例。
界面如下所示:
在这里插入图片描述

写内存widget-示例代码如下所示:

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QTextEdit>
#include <QByteArray>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget),
      sharememory("shareTest", this)
{
    ui->setupUi(this);

}

Widget::~Widget()
{
    delete ui;
}




void Widget::on_textEdit_textChanged()
{

    if(sharememory.isAttached()) {
        sharememory.detach();
    }
    QByteArray arr = ui->textEdit->toPlainText().toLocal8Bit();
    int len = arr.length();
    qDebug()<<ui->textEdit->toPlainText()<<len;
    if(!sharememory.create(len)) {
        qDebug() << sharememory.errorString();
        return ;
    }
    sharememory.lock();
    char *dest = reinterpret_cast<char *>(sharememory.data());
    for (int i = 0; i < len; i++) {
        dest[i] = arr[i];
    }
    sharememory.unlock();
}

读内存widget-示例代码如下所示:

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QTextEdit>
#include <QTimer>
#include <QByteArray>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget),
      sharememory("shareTest", this)
{
    ui->setupUi(this);
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(timeout()));
    timer->start(200);

}


void Widget::timeout()
{

    if (!sharememory.isAttached()) {
        if (!sharememory.attach()) {
            qDebug() << sharememory.errorString();
        } else {
            sharememory.lock();
            QByteArray arr((char*)sharememory.data(), sharememory.size());
            ui->textEdit->setPlainText(QString(arr));
            sharememory.unlock();
            sharememory.detach();
        }
    }

}

Widget::~Widget()
{
    delete ui;
}

3. Linux下查看共享内存

1、查看共享内存,使用命令:ipcs-m
2、删除共享内存,使用命令:ipcrm-m[shmid]

如下图所示:
在这里插入图片描述
1、key:共享内存的key
2、shmid:共享内存的编号
3、owner:共享内存的创建用户
4、perms:共享内存的权限
5、bytes:共享内存的大小
6、nattch:连接到共享内存的进程数
7、status:共享内存的状态

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QSharedMemory介绍 的相关文章

  • QGroupBox边框

    经过一段时间的搜索后 我发现在组框上设置可见边框的方法是使用 StyleSheet 属性 我补充道 border 2px solid gray 但有几个问题 1 组框内的所有内容也继承此设置 2 边框在标题附近有一个小洞 碎片缺失 Here
  • Qt、PushButton、id 属性?有什么方法可以知道点击了哪个按钮

    void MainWindow addRadioToUI int button cunter 4 while database isEmpty button cunter QPushButton one new QPushButton Pl
  • Windows 消息循环而不是 QApplication::exec() / QApplication::processEvents()

    我是否想念任何一个Qt如果我替换功能QApplication exec 使用标准 Windows 消息循环实现 这应该可以澄清我的意思 运行事件处理的常用 Qt 方式 int main int argc char argv QApplica
  • 安装多个版本的 Qt 库

    我在windows中安装了QtSDK 它的Qt库版本是4 7 0 现在我想为 mingw 和 VS2008 安装 Qt 库版本 4 8 2 我怎样才能做到这一点 如何向QtCreator引入多个版本 注意 我已经从以下位置下载了库http
  • 如何将图标放置到 QLineEdit 上?

    stackoverflow com 网站的右上角有一个带有放大镜头的搜索字段和一个灰色的 搜索 关键字 我想知道是否有可能实现相同的外观QLineEdit 如果是这样那怎么办 QLineEdit lineEdit new QLineEdit
  • QGraphicsView 和 eventFilter

    这个问题已经困扰我两天多了 所以我想我应该问一下 我在Win7上使用Qt 4 5 3 用VC2008编译 我有 MyGraphicsView 继承 QGraphicsView 和 MyFilter 继承 QObject 类 当我将 MyFi
  • 如何在 Qt-Embedded 中(正确)输出多语言文本?

    我的目标系统是 linux 3 3 7 Qt Embedded 开源版 4 8 Droid 字体 取自 fonts droid 20111207 git 1 all deb Debian 软件包并复制到 usr lib fonts目录 主要
  • (如何)我可以抑制未找到包配置文件的警告吗?

    我正在尝试创建一个CMakeLists txt尝试查找的文件Qt5 如果失败 则尝试回退到Qt4安装 该脚本到目前为止有效 但如果出现以下情况我总会收到警告Qt5未安装 注意FindQt5 cmake是由提供Qt5并且仅当以下情况时才可用Q
  • Qt中如何获取鼠标在屏幕上的位置?

    我想获取屏幕上的鼠标坐标 我怎样才能在 Qt 中做到这一点 在 Windows 上 使用 C 我正在做类似答案中建议的事情对于这个问题 https stackoverflow com q 11737665 1420197 正如文档所述 QC
  • Qt mouseReleaseEvent() 未触发?

    我有一个显示图片的库 我们称之为 PictureGLWidget 其中 class PictureGLWidget public QGLWidget 所以 PictureGLWidget 扩展了 QGLWidget 在PictureGlWi
  • QtCreator 调试暂停停在代码而不是汇编处

    如何配置 QtCreator 以便在调试并按下暂停时它会显示当前正在处理的代码 现在显示汇编 无法在任何地方找到有关此问题的答案 我使用的是 Windows 7 我在 Ubuntu 16 04 中使用 Qt Creator 4 2 2 时遇
  • Qt WinRT 应用程序无法访问文件权限被拒绝

    我需要使用 Qt 和 FFMPEG 开发 WinRT 应用程序 我根据指令构建了 WinRT 的 ffmpeghere https github com Microsoft FFmpegInterop我可以将库与我的项目链接起来 现在我需要
  • QTcpSocket 有时不发送数据

    我有两个 QT 应用程序 一个应用程序可以被认为保存了大数据 它每秒向第二个应用程序发送大约 10 KB 的数据块 之前我尝试使用QUdpSocket来传输数据 但由于MTU限制在2 5K左右 并且需要自己分割和重新组合数据 所以我改用QT
  • QTextEdit.find() 在 Python 中不起作用

    演示问题的简单代码 usr bin env python import sys from PyQt4 QtCore import QObject SIGNAL from PyQt4 QtGui import QApplication QTe
  • 禁用 QML Slider 的鼠标滚轮

    我希望能够滚动Flickable使用鼠标滚轮 或触摸板上的两根手指 不改变Sliders它可能包含 示例代码及结果应用 import QtQuick 2 7 import QtQuick Window 2 2 import QtQuick
  • 在 Qt5 中,是否需要 Q_INVOKABLE 来从 QML 调用公共 QObject 函数?

    我刚刚意识到我可以调用暴露于 QML 的对象的几乎任何函数 现在我对 Q INVOKABLE 很好奇 Qt5docs http doc qt io qt 5 qtqml cppintegration exposecppattributes
  • 如何将图像显示为缩略图

    我有一个QTreeView显示硬盘驱动器和目录 我也有一个QListView显示图像文件如下 但我想将图像显示为缩略图 如下所示 My code mainWidget mainWidget QWidget parent QWidget pa
  • 使用 QtWebEngine 将 C++ 对象暴露给 Qt 中的 Javascript

    使用 QtWebkit 可以通过以下方式将 C 对象公开给 JavascriptQWebFrame addToJavaScriptWindowObject如中所述https stackoverflow com a 20685002 5959
  • 如何使QTableView类的restoreState()和saveState()正常工作?

    首先 我想说 我的问题已经在这里讨论过 并且这里是 https stackoverflow com questions 1163030 qt qtableview and horizontalheader restorestate 但答案并
  • Qt:测量事件处理时间

    我想测量我的应用程序中的哪些事件在主线程中需要很长时间才能执行 阻塞 GUI 或者至少是否有任何事件花费的时间超过 比如说 10 毫秒 显然 我对需要很长时间的任务使用线程和并发 但有时很难在其他线程中放入的内容和可以保留在 GUI 中的内

随机推荐