Qt进程间通信(QSharedMemory、QLocalSocket、QWebSocket、QProcess、D-BUS、QTcpSocket)

通信方法:

1、QSharedMemory。

2、QLocalSocket。

3、QWebSocket。

4、QTcpSocket。

5、QProcess。

6、D-BUS

共享内存QSharedMemory

介绍 :共享内存指 (shared memory)在多处理器的计算机系统中,可以被不同中央处理器(CPU)访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache)。任何一个缓存的数据被更新后,由于其他处理器也可能要存取,共享内存就需要立即更新,否则不同的处理器可能用到不同的数据。共享内存是多进程之间的通信方法 ,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。
优点

1、速度快:由于数据直接存储在内存中,没有复制和数据转移的过程,所以速度很快。这使得共享内存通信无需进行数据的复制,多个进程或线程可以直接访问同一块内存区域,减少了CPU和内存的开销,具有较低的延迟和较高的带宽。

2、数据共享:多个进程可以同时访问同一块内存区域中的数据,实现数据共享。这种机制使得进程间的数据不用传送,而是直接访问内存,加快了程序的效率。

3、实时性:由于数据不需要复制和传输,共享内存通信延迟较低,能够满足对实时性要求较高的应用场景。

4、灵活性:共享内存可以支持多种数据结构和数据类型的共享,适应不同的应用场景。
应用场景 :更适用于两个进程间存在大批量数据访问的情况。
相关函数

cpp 复制代码
void QSharedMemory::setKey(const QString &key)
//指定身份字ID
bool QSharedMemory::create(int size, AccessMode mode=ReadWrite)
/*创建一个大小为size个字节的共享内存段, 然后用给定的访问模式mode附着到共享内存上。Mode取值有以下几种:
QSharedMemory::ReadOnly : 共享内存段是只读的。不允许写入共享内存段。尝试写入使用ReadOnly创建的共享内存段会导致程序中止。
QSharedMemory::ReadWrite : 允许对共享内存段进行读写操作。*/
bool QSharedMemory::attach(AccessMode mode = ReadWrite)
//尝试将共享内存绑定到进程上,如果绑定操作成功,则返回true。如果失败返回false,可调用error()或者errorString()来确定发生了哪个错误。在附加共享内存段成功之后,则可以通过调用data()来获得一个指向共享内存的指针。
bool QSharedMemory::isAttached() const
//判断共享内存是否绑定进程成功。
bool QSharedMemory::detach()
//将进程和共享内存段解绑。如果这是连接到共享内存段的最后一个进程,那么共享内存段将被系统释放,也就是说,内容将被销毁。如果解绑共享内存段完成,则返回true。如果失败返回false,并意味着该段没有连接,或者被另一个进程锁定。
bool QSharedMemory::lock()
//用来锁定共享内存的互斥值,锁住成功则返回true. 若另一个进程已经锁住了共享内存段,本函数将会阻塞直到锁被另一个进程释放。到那时,本函数才会获得锁并返回true. 如果本函数返回false,那就说明你已经忽略了一个由create()或attach()返回的false,而其原因可能是由于某个系统错误而导致setNativeKey()或QSystemSemaphore::acquire()失败。
bool QSharedMemory::unlock()
//释放共享内存段上的锁并返回true,如果共享内存段没有被lock,或者如果锁被其他进程持有,本函数什么都不会做而只是返回false. 
void * QSharedMemory::data()
//如果附加了共享内存段,则返回指向共享内存段内容的指针。否则返回null。在对共享内存进行读写操作之前,记得使用lock()锁定共享内存,并且记得在操作完成后使用unlock()释放锁。
const void *QSharedMemory::constData() const
//与data一样。区别是该数据是只读的。

注意 :QSharedMemory往往还被用来做防止软件重复打开。
详细介绍及代码实例

本地通信QLocalSocket

介绍 :在windows它是一个命名管道,在unix中它是一个本地socket。(IPC)
优点

1、简单的 API。

2、跨平台。

3、安全性:在 Unix 系统上,本地套接字通信是基于文件系统的权限系统的,因此可以提供一定程度的安全性。

4、异步操作:不会阻塞事件循环,从而允许其他事件同时处理。

5、即时通信:由于数据是在内存中直接操作,所以消息传递非常迅速,几乎无延迟,适合实时性要求高的场景。
关联类 :QLocalServer和QLocalSocket配套使用。
应用场景 :同一台设备上多个进程间通信。
相关函数

cpp 复制代码
bool QLocalServer::removeServer(const QString &name)
//删除已有的连接。
bool QLocalServer::listen(const QString &name)
//开启对name标识的监听。
[signal] void QLocalServer::newConnection()
//每当有新的客户端连接可用时,就会发出此信号。
QLocalSocket *QLocalServer::nextPendingConnection()
//获取连接的客户端socket对象。
[signal] void QIODevice::readyRead()
//每当有新的数据时,就会发出此信号。
QByteArray QIODevice::readAll()
//获取接收的数据。
qint64 QIODevice::write(const char *data, qint64 maxSize)
//发送数据
[signal] void QLocalSocket::disconnected()
//每当有连接断开时,就会发出此信号。
[signal] void QLocalSocket::error(QLocalSocket::LocalSocketError socketError)
//每当存在错误信息时,就会发出此信号。
void QLocalSocket::connectToServer(const QString &name, QIODevice::OpenMode openMode = ReadWrite)
//连接指定name标识的客户端,openMode可设置连接方式。

详细介绍及代码实例1
详细介绍及代码实例2

QWebSocket

介绍 :WebSocket 是一种网络传输协议,可在单个 TCP 连接上进行全双工通信,位于 OSI 模型的应用层。
优点

1、较少的控制开销:在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小;

2、性能:由于WebSocket是基于TCP的,相比HTTP减少了握手过程,使得数据传输更快速。

3、更好的二进制支持:WebSocket 定义了二进制帧,相对 HTTP,可以更轻松地处理二进制内容;

4、稳定性与安全性:WebSocket协议本身提供了一种安全可靠的通信方式,QWebSocket在实现中遵循标准,确保数据传输的安全性。
关联类 :QWebSocketServer和QWebSocket配套使用。
应用场景 :广泛地应用在即时通讯/IM、实时音视频、在线教育和游戏等领域。
相关函数

cpp 复制代码
QWebSocketServer::QWebSocketServer(const QString &serverName, QWebSocketServer::SslMode secureMode, QObject *parent = nullptr)
/*使用给定的serverName构造一个新的QWebSocketServer。该服务器名称将在HTTP握手阶段被用来识别服务器。它可以为空,此时不会将服务器名称发送给客户端。
SslMode指示服务器是通过wss(SecureMode)还是ws(NonSecureMode)运行。QWebSocketServer::SecureMode服务器以安全模式运行(通过wss);QWebSocketServer::NonSecureMode服务器以非安全模式运行(通过ws)*/
void QWebSocketServer::setServerName(const QString &serverName)
//使用给定的serverName构造一个新的QWebSocketServer。该服务器名称将在HTTP握手阶段被用来识别服务器。它可以为空,此时不会将服务器名称发送给客户端。
bool QWebSocketServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)
//监听指定的IP和端口。
[signal] void QWebSocketServer::newConnection()
//每当有新的客户端连接可用时,就会发出此信号。
QWebSocket *QWebSocketServer::nextPendingConnection()
//获取连接的客户端socket对象。
[signal] void QWebSocket::disconnected()
//每当有连接断开时,就会发出此信号。
QAbstractSocket::SocketError QWebSocket::error() const
//每当存在错误信息时,就会发出此信号。
[signal] void QWebSocket::textMessageReceived(const QString &message)
//每当接收到文本消息时,就会发出此信号。该消息包含收到的文本。常用来数据交互
[signal] void QWebSocket::binaryMessageReceived(const QByteArray &message)
//每当接收到二进制消息时,就会发出此信号。该消息包含接收到的字节。常用于文件发送
qint64 QWebSocket::sendTextMessage(const QString &message)
//发送文本数据
qint64 QWebSocket::sendBinaryMessage(const QByteArray &data)
//发送二进制数据
void QWebSocket::open(const QUrl &url)
//客户端开启连接请求,url格式:QString(ws://%1:%2).arg(ip).arg(port)

详细介绍及代码实例1
详细介绍及代码实例2

QTcpSocket

介绍 :TCP提供一种机制可以让发送端根据接收端的实际接收能力控制发送的数据量,是一种流控制。
优点

1、高效率:QTcpSocket利用了Qt的事件驱动架构,确保数据传输的高效处理。它会自动管理套接字的读写操作,并利用底层操作系统的能力进行优化。

2、实时性:对于需要实时通讯的应用程序,提供低延迟的数据传输。

3、异步操作:不会阻塞事件循环,从而允许其他事件同时处理。

4、跨平台。

5、安全性:QTcpSocket可以处理加密通信,支持SSL/TLS(Secure Sockets Layer/Transport Layer Security),增强了数据传输的安全性。
关联类 :QTcpServer和QTcpSocket配套使用。
应用场景 :更适用于不同设备上的进程间的网络通信
相关函数

cpp 复制代码
bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)
//告诉服务器监听地址和端口端口上的传入连接。如果端口为0,则会自动选择端口。如果地址为QHostAddress::Any,则服务器将侦听所有网络接口。成功时返回true;否则返回false。
[signal] void QTcpServer::newConnection()
//每当有新的客户端连接可用时,就会发出此信号。
QTcpSocket *QTcpServer::nextPendingConnection()
//获取连接的客户端socket对象。
[signal] void QAbstractSocket::disconnected()
//每当有连接断开时,就会发出此信号。
QAbstractSocket::SocketError QAbstractSocket::error() const
//每当存在错误信息时,就会发出此信号。
[signal] void QIODevice::readyRead()
/*每当有新数据可用于从设备的当前读取通道读取时,该信号就会发出一次。只有当新数据可用时,例如当网络数据的新有效载荷到达网络套接字时,或者当新的数据块附加到设备时,它才会再次发出。
readyRead()不是递归发出的;如果重新进入事件循环或在连接到readyRead()信号的插槽内调用waitForReadyRead(),则该信号将不会重新出现(尽管waitForReadRead()可能仍返回true)。
对于实现从QIODevicece派生的类的开发人员来说,请注意:当新数据到达时,您应该始终发出readyRead()(不要仅仅因为缓冲区中还有数据要读取而发出它)。不要在其他条件下发出readyRead()。*/
QByteArray QIODevice::readAll()
//获取接收的数据。
qint64 QIODevice::write(const char *data, qint64 maxSize)
//发送数据
void QAbstractSocket::connectToHost(const QString &hostName, quint16 port, QIODevice::OpenMode openMode = ReadWrite, QAbstractSocket::NetworkLayerProtocol protocol = AnyIPProtocol)
//连接指定IP和端口的客户端,protocol可单独指定IPV4和IPV6。默认情况都支持。

详细介绍及代码实例1
详细介绍及代码实例2

QProcess

介绍 :QProcess提供了在 Qt 应用程序中启动外部程序的方法。通过QProcess,你可以启动一个进程,与它通信(发送输入和读取输出),检查它的状态,以及等待它完成。这个类在执行系统命令、运行其他程序或脚本时非常有用。(IPC)
优点

1、异步操作:QProcess支持非阻塞操作,可以在子进程执行的同时继续执行主线程的任务,提高程序的响应性和效率。

2、跨平台兼容。

3、丰富的功能:支持启动、控制、监控和终止外部程序,获取输出和错误信息,以及设置环境变量和传递参数。

4、管道和重定向:支持输入/输出管道,使得进程之间的数据交换变得方便。
关联类 :进程通信时需要和QSocketNotifier配套使用。
应用场景 :使用于同一台设备上进程间的通信
相关函数

cpp 复制代码
void QProcess::start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode = ReadWrite)
//异步启动进程,可带参数启动,可设置启动进程的读写方式。父子进程不分离,父进程退出,子进程同步退出。
bool QProcess::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory = QString(), qint64 *pid = nullptr)
//异步启动进程,可带参数启动,父子进程分离,父进程退出,子进程不会同步。
qint64 QIODevice::write(const char *data, qint64 maxSize)
//写入数据。
QByteArray QProcess::readAllStandardOutput()
//无论当前读取通道状态如何,此函数都会以QByteArray的形式返回过程标准输出的所有可用数据。
bool QProcess::waitForFinished(int msecs = 30000)
//阻塞在当前位置,等待start或者startDetached执行完毕完毕,具有超时功能,一般用来获取子进程启动后的返回结果。
[signal] void QSocketNotifier::activated(int socket)
//用于父进程发送数据后,通知子进程的信号。
[signal] void QIODevice::readyRead()
//获取接收的数据。

详细介绍及代码实例1
详细介绍及代码实例2子进程读的方式通过read读取标准输出。
详细介绍及代码实例3子进程读的方式通过线程遍历获取。

D-BUS

介绍 :D-Bus是一种高级的进程间通信机制。D-Bus最主要的用途是在Linux桌面环境为进程提供通信,同时能将Linux桌面环境和Linux内核事件作为消息传递到进程。D-Bus是一个消息总线系统。(IPC)

D-Bus是三层架构的进程间通信系统,其中包括:

接口层:接口层由函数库libdbus提供,进程可通过该库使用D-Bus的能力。

总线层:总线层实际上是由D-Bus总线守护进程提供的。它在Linux系统启动时运行,负责进程间的消息路由和传递,其中包括Linux内核和Linux桌面环境的消息传递。

包装层:一系列基于特定应用程序框架的Wrapper库。
优点

1、支持不同进程间信号槽的连接。

2、异步操作。不阻塞当前进程。

3、低延迟。

4、低开销,使用一个二进制的协议,不需要转化成像XML这样的文本格式。因为DBus是主要用来机器内部的IPC,而不是为了网络上的IPC机制而准备的.所以它才能够在本机内部达到最优效果。

5、高可用性,DBus是基于消息机制而不是字节流机制。它能自动管理一大堆困难的IPC问题。同样的,DBus库被设计来让程序员能够使用他们已经写好的代码。而不会让他们放弃已经写好的代码,被迫通过学习新的IPC机制来根据新的IPC特性重写这些代码。
关联类

QDBusMessage(用于消息发送)

QDBusInterface(用于消息发送)

QDBusConnection(用于连接、注册、发送)
应用场景 :同一台linux系统下的设备上。
相关函数

cpp 复制代码
[static] QDBusConnection QDBusConnection::sessionBus()
//返回使用会话总线打开的QDBusConnection对象。此函数返回的对象引用在应用程序终止之前一直有效,此时连接将关闭,对象将被删除。
bool QDBusConnection::registerService(const QString &serviceName)
//尝试在D-Bus服务器上注册serviceName,如果注册成功,则返回true。如果该名称已由另一个应用程序注册,则注册将失败。
bool QDBusConnection::registerObject(const QString &path, const QString &interface, QObject *object, QDBusConnection::RegisterOptions options)
//使用接口名称注册路径上的对象
Q_CLASSINFO(Name, Value)
//此宏将额外信息关联到类、额外信息采用Name字符串和Value文本字符串的形式。用于关联D-BUS服务器接口的。
bool QDBusConnection::connect(const QString &service, const QString &path, const QString &interface, const QString &name, QObject *receiver, const char *slot)
//将服务名称、临时约定路径、接口名称和临时连接名称相关参数指定的信号连接到对象接收器中的槽函数。服务标识和路径可以为空,表示从任何远程应用程序到(接口、名称)对的任何信号的连接。
[static] QDBusMessage QDBusMessage::createSignal(const QString &path, const QString &interface, const QString &name)
//构造一个具有临时约定路径、接口名和临时连接名称的新DBus消息。
bool QDBusConnection::send(const QDBusMessage &message) const
//通过此连接发送消息,无需等待答复。
[static] QDBusMessage QDBusMessage::createMethodCall(const QString &service, const QString &path, const QString &interface, const QString &method)
//构造一个表示方法调用的新DBus消息,
QDBusMessage QDBusConnection::call(const QDBusMessage &message, QDBus::CallMode mode = QDBus::Block, int timeout = -1) const
//通过此连接发送消息,并阻塞等待回复,支持超时结束。
QDBusInterface::QDBusInterface(const QString &service, const QString &path, const QString &interface = QString(), const QDBusConnection &connection = QDBusConnection::sessionBus(), QObject *parent = nullptr)
//创建一个绑定服务器名称、fuwuq路径、接口名的interface对象,作为发送数据使用。
QDBusMessage QDBusAbstractInterface::call(const QString &method, const QVariant &arg1 = QVariant(), const QVariant &arg2 = QVariant(), const QVariant &arg3 = QVariant(), const QVariant &arg4 = QVariant(), const QVariant &arg5 = QVariant(), const QVariant &arg6 = QVariant(), const QVariant &arg7 = QVariant(), const QVariant &arg8 = QVariant())
//通过此连接调用接口中注册的方法。并将此函数的参数传递给该方法。接口类中的所以槽函数都是注册方法。

详细介绍及代码实例1

相关推荐
Java探秘者14 分钟前
Maven下载、安装与环境配置详解:从零开始搭建高效Java开发环境
java·开发语言·数据库·spring boot·spring cloud·maven·idea
攸攸太上15 分钟前
Spring Gateway学习
java·后端·学习·spring·微服务·gateway
2301_7869643620 分钟前
3、练习常用的HBase Shell命令+HBase 常用的Java API 及应用实例
java·大数据·数据库·分布式·hbase
Geek之路1 小时前
QT系统学习篇(1)
开发语言·qt·学习
阿维的博客日记1 小时前
图文并茂解释水平分表,垂直分表,水平分库,垂直分库
数据库·分库分表
wrx繁星点点2 小时前
事务的四大特性(ACID)
java·开发语言·数据库
小小娥子3 小时前
Redis的基础认识与在ubuntu上的安装教程
java·数据库·redis·缓存
DieSnowK3 小时前
[Redis][集群][下]详细讲解
数据库·redis·分布式·缓存·集群·高可用·新手向
-XWB-3 小时前
【MySQL】数据目录迁移
数据库·mysql
老华带你飞3 小时前
公寓管理系统|SprinBoot+vue夕阳红公寓管理系统(源码+数据库+文档)
java·前端·javascript·数据库·vue.js·spring boot·课程设计