Qt中是否有进程内本地管道? [英] Is there an intra-process local pipe in Qt?

查看:828
本文介绍了Qt中是否有进程内本地管道?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Qt是否有 QIODevice 对可以用于内部点对点通信?

Does Qt have a QIODevice pair that would work for intra-process point-to-point communications?

可以使用具体的 QTCPSocket QLocalSocket ,但是服务器端连接API是一个有点麻烦,并且通过操作系统强制数据似乎是浪费。

One could use the concrete QTCPSocket or QLocalSocket, but the server-side connection API is a bit cumbersome, and it seems wasteful to force the data through the OS.

推荐答案

以下是一个可用的, 。它使用内部信号槽对将数据推送到另一个端点。这样,连接的任一端可以存在于任何线程中,并且可以在线程之间移动端点,而不丢失数据或诱发任何比赛。

The following is a usable, rudimentary implementation. It uses an internal signal-slot pair to push the data to the other endpoint. That way either end of the connection can live in any thread, and the ends can be moved between threads without losing data or inducing any races.

私人 QRingBuffer 用于代替重新发明轮子。将 QT + = core-private 添加到 .pro 文件以使其可用。

The private QRingBuffer is used in lieu of reinventing the wheel. Add QT += core-private to the .pro file to make that available.

在没有设置其他端点的情况下初始化时,必须将明确的 nullptr 作为构造函数的第一个参数传递。这有助于避免端点和对象父对象之间的混淆。

When initializing without the other endpoint set, you must pass an explicit nullptr as the first argument to the constructor. This helps to avoid confusion between the endpoint and the object parent.

如果你想实例化一个开放的管道,通常情况下,你可以传递I / O模式到构造函数。典型用途:

If you wish to instantiate an open pipe, as may often be the case, you can pass the I/O mode to the constructor. Typical use:

int main( . . . ) {
  AppPipe end1 { nullptr, QIODevice::ReadWrite };
  AppPipe end2 { &end1, QIODevice::ReadWrite };
  end1.addOther(&end2);
  // the pipes are open ready to use
}

到一个管道,结束作为另一个中的可读数据,反之亦然。所有 QIODevice 语义持有 - 您可以连接到 readyRead 信号,使用管道与 QDataStream QTextStream 等。与任何 QIODevice 使用 thread()中的类,但是另一个端点可以存在于任何线程中,并且可以根据需要在线程之间移动,而不会丢失数据。

Whatever you write to one pipe, ends up as readable data in the other, and vice versa. All of the QIODevice semantics hold - you can connect to the readyRead signal, use the pipe with a QDataStream or a QTextStream, etc. As with any QIODevice, you can only use the class from its thread(), but the other endpoint can live in any thread, and both can be moved between threads as desired, without loss of data.

如果另一个管道末端未打开并且可读,则写入操作是空操作,即使它们成功。

If the other pipe end is not open and readable, the writes are no-ops, even though they succeed. Closing the pipe clears the read buffer, so that it can be re-opened for reuse.

hasIncoming ,并且可以重新打开读取缓冲区, hasOutgoing 信号在监控通过管道的数据时非常有用。 p>

The hasIncoming and hasOutgoing signals are useful in monitoring the data going over the pipe.

#include <private/qringbuffer_p.h>

/// A simple point-to-point intra-process pipe. The other endpoint can live in any
/// thread.
class AppPipe : public QIODevice {
   Q_OBJECT
   QRingBuffer m_buf;
   void _a_write(const QByteArray & data) {
      if (! openMode() & QIODevice::ReadOnly) return; // We must be readable.
      m_buf.append(data);
      emit hasIncoming(data);
      emit readyRead();
   }
public:
   AppPipe(AppPipe * other, QIODevice::OpenMode mode, QObject * parent = 0) :
      QIODevice(parent) {
      addOther(other);
      open(mode);
   }
   AppPipe(AppPipe * other, QObject * parent = 0) : QIODevice(parent) {
      addOther(other);
   }
   void addOther(AppPipe * other) {
      if (other) connect(this, &AppPipe::hasOutgoing, other, &AppPipe::_a_write);
   }
   void removeOther(AppPipe * other) {
      disconnect(this, &AppPipe::hasOutgoing, other, &AppPipe::_a_write);
   }
   void close() Q_DECL_OVERRIDE {
      QIODevice::close();
      m_buf.clear();
   }
   qint64 writeData(const char * data, qint64 maxSize) Q_DECL_OVERRIDE {
      if (!maxSize) return maxSize;
      hasOutgoing(QByteArray(data, maxSize));
      return maxSize;
   }
   qint64 readData(char * data, qint64 maxLength) Q_DECL_OVERRIDE {
      return m_buf.read(data, maxLength);
   }
   qint64 bytesAvailable() const Q_DECL_OVERRIDE {
      return m_buf.size() + QIODevice::bytesAvailable();
   }
   bool canReadLine() const Q_DECL_OVERRIDE {
      return QIODevice::canReadLine() || m_buf.canReadLine();
   }
   bool isSequential() const Q_DECL_OVERRIDE { return true; }
   Q_SIGNAL void hasOutgoing(const QByteArray &);
   Q_SIGNAL void hasIncoming(const QByteArray &);
};





#local-pipe-32317081.pro
QT       += core-private
TARGET = local-pipe-32317081
CONFIG   += c++11
TEMPLATE = app
SOURCES += main.cpp

这篇关于Qt中是否有进程内本地管道?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆