c++ - 使用 QThread 时类型转换和 QThreadStorage 警告?

标签 c++ qt qthread

我对使用QThread非常陌生。我正在使用 QThread 从 Axis Ip 摄像机抓取图像。在以下代码片段中,我将相机类移至新线程:

QThread camThread;
camera = new AxisNetworkCamera();
camera->moveToThread(&camThread);
camThread.start();
connect(camera, SIGNAL(imageUpdate(QImage)), this, SLOT(upDateImage(QImage)));
connect(camera, SIGNAL(cameraDisconnected()), this, SLOT(cameraDisconnected()));
connect(&camThread, &QThread::finished, &camThread, &QThread::deleteLater);
connect(camera, &AxisNetworkCamera::destroyed, &camThread, &QThread::quit);

我正在调用启动相机的函数:

QMetaObject::invokeMethod(camera, "deviceStartup", Qt::QueuedConnection, Q_ARG(QString, QString::fromStdString(streamUrl)));

应用程序运行良好,当我关闭它时也可以正常关闭,但我担心的是一些警告消息。

第一个是当我启动相机时:

Type conversion already registered from type QPair<QByteArray,QByteArray> to type QtMetaTypePrivate::QPairVariantInterfaceImpl

第二个是当我关闭应用程序时:

QThreadStorage: Thread 0x7fffb8004da0 exited after QThreadStorage 7 destroyed

我应该担心这些消息吗?它们,特别是第二个 1,是否意味着内存管理不善?

谢谢

最佳答案

您发布的代码毫无意义。 QThread 不是动态分配的,因此您无法删除它:deleteLater 调用将会崩溃。它可能永远不会被执行,因为您没有显示任何会停止线程的代码。在相机被销毁后销毁线程也是没有意义的。

安全执行操作的最简单方法是在类中按值保存相机和线程,并按正确的顺序声明它们,以便线程在相机之前被销毁。那时,相机就变成无线程的,并且可以在任何线程中安全地销毁。

还有一种比使用 invokeMethod 更好的方法来调用远程线程中的方法:

class Thread : public QThread {
  using QThread::run; // final
public:
  Thread(QObject*parent = 0): QThread(parent) {}
  ~Thread() { quit(); wait(); }
};

// See http://stackoverflow.com/a/21653558/1329652 for details about invoke.
template <typename F> void invoke(QObject * obj, F && fun) {
  if (obj->thread == QThread::currentThread())
    return fun();
  QObject src;
  QObject::connect(&src, &QObject::destroyed, obj, std::forward<F>(fun));
}

class MyObject : public QObject {
  Q_OBJECT
  AxisNetworkCamera camera;
  Thread camThread { this };
  Q_SLOT void updateImage(const QImage &);
  Q_SLOT void cameraDisconnected();
public:
  MyObject(QObject * parent = 0) : QObject(parent)
  {
    connect(&camera, &AxisNetworkCamera::imageUpdate, this, &MyObject::updateImage);
    connect(&camera, &AxisNetworkCamera::cameraDisconnected, this, &MyObject::cameraDisconnected);
    camera.moveToThread(&camThread);
    camThread.start();
  }
  void startCamera(const QString & streamUrl) {
    invoke(&camera, [=]{ camera.deviceStartup(streamUrl); });
  }
};

关于c++ - 使用 QThread 时类型转换和 QThreadStorage 警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37479492/

相关文章:

c++ - 通用正则表达式变音解决方案?

python - 在pyqt中运行另一个进程时旋转动画

c# - 如何从托管代码调试英特尔 C++ 库?

函数作为参数的 C++ 错误,对非常量的引用的初始值必须是左值

c++ - 带有 Win32 HWND 嵌入的 Qt5 QWidget::create() 在从 Qt4 移植后不再工作

c++ - Qt:父子关系如何影响子部件的布局?

c++ - 对字符串数组进行归并排序

c++ - 使用或不使用指针制作数据成员对象

c++ - 无法发出 QThread 的信号

python - 使用 QThread 和 pyqtSignal,为什么不同线程中的进程会卡住 GUI?