Qt中的进程间通信(IPC)
Qt 提供了几种在 Qt 应用程序中实现进程间通信(IPC)的方法。
TCP/IP
跨平台的 Qt Network 模块提供了一些类,使网络编程变得便携和简单。它提供了高级类(如 QNetworkAccessManager),这些类使用特定的应用层协议进行通信,还有低级类(如 QTcpSocket、QTcpServer、QSslSocket)用于实现协议。
示例代码
下面是一个简单的使用 QTcpSocket
和 QTcpServer
的示例:
// 服务器端
QTcpServer *server = new QTcpServer(this);
connect(server, &QTcpServer::newConnection, this, &MyClass::onNewConnection);
if (!server->listen(QHostAddress::Any, 1234)) {
qFatal("Failed to bind to port");
}
void MyClass::onNewConnection() {
QTcpSocket *clientSocket = server->nextPendingConnection();
connect(clientSocket, &QTcpSocket::readyRead, this, &MyClass::onReadyRead);
}
void MyClass::onReadyRead() {
QTcpSocket *clientSocket = qobject_cast<QTcpSocket*>(sender());
QByteArray data = clientSocket->readAll();
// 处理接收到的数据
}
// 客户端
QTcpSocket *socket = new QTcpSocket(this);
socket->connectToHost("localhost", 1234);
if (socket->waitForConnected(3000)) {
socket->write("Hello, Server!");
}
本地服务器/套接字
跨平台的 Qt Network 模块提供了一些类,使本地网络编程变得便携和简单。它提供了 QLocalServer 和 QLocalSocket 类,这些类允许在本地设置中进行类似网络的通信。它们的 TCP 对应类可以作为替代品,使通信在网络上工作。
示例代码
下面是一个使用 QLocalServer
和 QLocalSocket
的简单示例:
// 服务器端
QLocalServer *server = new QLocalServer(this);
connect(server, &QLocalServer::newConnection, this, &MyClass::onNewLocalConnection);
if (!server->listen("MyLocalServer")) {
qFatal("Failed to bind to local server");
}
void MyClass::onNewLocalConnection() {
QLocalSocket *clientSocket = server->nextPendingConnection();
connect(clientSocket, &QLocalSocket::readyRead, this, &MyClass::onLocalReadyRead);
}
void MyClass::onLocalReadyRead() {
QLocalSocket *clientSocket = qobject_cast<QLocalSocket*>(sender());
QByteArray data = clientSocket->readAll();
// 处理接收到的数据
}
// 客户端
QLocalSocket *socket = new QLocalSocket(this);
socket->connectToServer("MyLocalServer");
if (socket->waitForConnected(3000)) {
socket->write("Hello, Local Server!");
}
共享内存
跨平台的共享内存类 QSharedMemory 提供了对操作系统的共享内存实现的访问。它允许多个线程和进程安全地访问共享内存段。此外,QSystemSemaphore 可以用于控制系统共享资源的访问,以及在进程之间进行通信。
示例代码
下面是一个简单的使用 QSharedMemory
和 QSystemSemaphore
的示例:
// 进程 A
QSharedMemory sharedMemory("MySharedMemoryKey");
QSystemSemaphore semaphore("MySemaphoreKey", 1);
semaphore.acquire();
if (sharedMemory.create(1024)) {
char *to = (char*)sharedMemory.data();
const char *from = "Hello from process A";
memcpy(to, from, qMin(sharedMemory.size(), 1024));
}
semaphore.release();
// 进程 B
QSharedMemory sharedMemory("MySharedMemoryKey");
QSystemSemaphore semaphore("MySemaphoreKey", 1);
semaphore.acquire();
if (sharedMemory.attach()) {
char *from = (char*)sharedMemory.data();
QByteArray byteArray(from, sharedMemory.size());
qDebug() << "Data from shared memory:" << byteArray;
sharedMemory.detach();
}
semaphore.release();
D-Bus 协议
Qt D-Bus 模块是一个 Unix 专用库,您可以使用它通过 D-Bus 协议实现 IPC。它将 Qt 的信号和槽机制扩展到 IPC 级别,允许一个进程发出的信号连接到另一个进程的槽。Qt D-Bus 文档详细介绍了如何使用 Qt D-Bus 模块。
示例代码
下面是一个简单的使用 Qt D-Bus 的示例:
// 发送端
QDBusInterface interface("com.example.service", "/ExampleObject", "com.example.Interface", QDBusConnection::sessionBus());
interface.call("ExampleMethod", "Hello from sender");
// 接收端
class ExampleReceiver : public QObject {
Q_OBJECT
public slots:
void ExampleMethod(const QString &message) {
qDebug() << "Received message:" << message;
}
};
// main.cpp
QDBusConnection::sessionBus().connect("com.example.service", "/ExampleObject", "com.example.Interface", "ExampleMethod", receiver, SLOT(ExampleMethod(QString)));
QProcess 类
跨平台类 QProcess 可用于启动外部程序作为子进程,并与它们进行通信。它提供了一个 API,用于监控和控制子进程的状态。QProcess 通过继承 QIODevice 提供对子进程输入/输出通道的访问。
示例代码
下面是一个使用 QProcess
的简单示例:
// 父进程
QProcess *process = new QProcess(this);
connect(process, &QProcess::readyRead, this, &MyClass::onProcessReadyRead);
process->start("child_program");
void MyClass::onProcessReadyRead() {
QByteArray output = process->readAll();
qDebug() << "Output from child process:" << output;
}
// 子进程 (child_program)
int main() {
qDebug() << "Hello from child process";
return 0;
}
会话管理
在 Linux/X11、Windows 和 macOS 上,Qt 提供会话管理支持。会话允许事件传播到进程,例如,在发生关机时通知进程。进程和应用程序可以执行任何必要的操作,例如保存打开的文档。
示例代码
下面是一个使用 QSessionManager
的简单示例:
void MyClass::saveState(QSessionManager &manager) {
if (manager.allowsInteraction()) {
// 保存文档或其他重要状态
manager.release();
} else {
// 保存最少的状态信息
}
}
// main.cpp
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MyClass myClass;
QObject::connect(&app, &QGuiApplication::commitDataRequest, &myClass, &MyClass::saveState);
return app.exec();
}