如何制作 Qt 线程包装器

Posted

技术标签:

【中文标题】如何制作 Qt 线程包装器【英文标题】:How to make a Qt thread wrapper 【发布时间】:2011-10-28 17:53:22 【问题描述】:

我已经编写了一些库代码(用 C 语言)以方便创建和查询独立于平台的线程。这是创建线程的 API 的伪代码示例:

 result OS_createThread ( 
      pointer to thread handle (set after thread is created), 
      stack size,
      function to run, 
      pointer to parameters,
      priority )

根据平台,我使用包含特定操作系统实现的适当 c 文件来启动线程。例如

result OS_createThread ( 
 // Windows implementation
 map priority to Windows priority
 // Use Win32 threading call
 CreateThread(blah blah)

我已经为 Win32、POSIX 线程和一些我使用过的 RTOS 创建了端口。现在我需要为 Qt 环境执行此操作,我有点难过。首先,我是一个 Qt 新手,其次它看起来需要使用 QThread 类的面向对象的方法。

这样做的目的是向调用者隐藏线程创建的内容。调用者希望能够启动线程并维护该线程的句柄,以便它可以在将来执行一些操作,例如更改其优先级或终止它。

使用QThreads,每次请求新线程时是否需要创建一个新的QThread对象?请记住,调用代码不能包含任何特定于 Qt 的内容。

感谢任何指导!

【问题讨论】:

【参考方案1】:

要创建一个 QThread,你需要实现一个继承自 QThread 的类。示例取自QT Documentation

class MyThread : public QThread
 
 public:
     void run();
 ;

 void MyThread::run()
 
     QTcpSocket socket;
     // connect QTcpSocket's signals somewhere meaningful
     ...
     socket.connectToHost(hostName, portNumber);
     exec();
 

隐藏在您的实现中的是:

result OS_createThread ( 
      pointer to thread handle (set after thread is created), 
      stack size,
      function to run, 
      pointer to parameters,
      priority )

  MyThread *thread = new MyThread(size, function, parameters, prio);
  thread->start();
  return thread;

所以你的 C 接口方法会为每个被请求的线程创建一个这样的类的实例。然后,该类应将从您的函数传递的所有相关数据存储在其成员变量中。要执行的线程函数将在run() 方法中调用。由于您似乎只执行 C 方法,我认为在类变量中存储指向它们的指针没有问题(如果我错了,请纠正我 - 还没有尝试过;)。

然而,它实际上比这更棘手,因为有人必须释放为thread 变量创建的内存。在我的示例中,这并不容易(从 C 接口)。因此,您可能需要考虑使用内部管理器类或处理创建的线程并根据需要销毁它们的东西。但是,为了就如何实现这一目标做出合格的陈述,我需要更多信息;)

【讨论】:

从QThread继承并不是Qt 4.4版本以后创建线程的最佳实践。请注意,即使是 Qt 文档也不是最新的。 qt developers blog 有一篇非常好的文章,介绍了在 Qt 中实现线程的最佳方式。 好点我不知道所以感谢您的提示。但是,答案的基本原则应该保持不变。所以要遵守新的约定并相应地实施包装器。 美丽。为了处理停止线程和释放内存,还有一个 API 函数 OS_destroyThread()。它需要线程的句柄。我只是将句柄转换为“MyThread”类型的指针,调用 terminate()、wait(),然后“删除”指针。这会杀死线程并清理内存。感谢您的帮助!【参考方案2】:

如果调用代码不是Qt特有的,为什么要使用或实现QThread-s?

如果您的目标是将 QThread-s(实际上是 QCore 库)移植到您奇怪的操作系统,我将首先详细研究他们如何在 Pthreads 之上实现它(假设您已经非常了解 posix 线程的详细信息)。

【讨论】:

我的代码需要移植到 Qt 应用程序中。那部分是我无法控制的。我的代码几乎是标准的 ANSI C,唯一依赖于平台的是线程、互斥锁等。所以我需要编写这个包装层。我的理解是,我不能简单地在 Qt 应用程序中创建 pthread(这将在 Linux 上运行)。 QThread 是 C++ 的东西。您需要学习 C++ 才能使用它们。而且我不确定您不能在使用 Qt 的代码中使用 pthread-s。在将你的胶水移植到 QThread-s 之前,我会先尝试。

以上是关于如何制作 Qt 线程包装器的主要内容,如果未能解决你的问题,请参考以下文章

我将如何制作一个 linkvertise 包装器

qt - 如何制作带有一组按钮的拆分器?

OSX 中 Carbon C 应用程序的异常包装器

我可以为任何可以放入 Extern C 的 C++ 向量制作一个 C 包装器吗

使用泛型制作 Array.flat(1) 的 Typescript 包装器

Flutter:使用包装器时如何使用Routes在页面之间进行路由