我可以使用QTimer来取代QThread吗?

时间:2014-05-09 02:18:37

标签: c++ multithreading qt

更确切地说,问题应该是:

将信号 QTimer::timeout 连接到我的工作函数并使用 <创建工作线程之间有什么区别? / strong> QThread


我正在编写一个程序,它接收主线程中的流数据(信号由QIODevice::readread()生成)并同时处理它们。现在我开始QTimer持续发射信号QTimer::timeout,并且信号连接到主线程中的工作函数,该函数执行数据处理。这就是我实现并发的方式。

我想知道这种方法是否与使用QThread创建另一个线程不同,因为我在this topic中找到的想法与我所做的非常相似。唯一的区别是接受的答案会创建另一个线程并在其上移动计时器和工作类。除了区别之外,我看不出在我的情况下使用线程的必要性。

在我的情况下(在主线程中接收数据并同时处理它们),我使用QTimer做得好还是应该创建QThread?我对多线程很陌生,如果我误解了什么,请帮助纠正我。谢谢。


[编辑]:

我不知道创建新线程来处理数据的区别/优势是什么。现在,一切都在一个线程中进行:我将数据保存在队列中,并在由QTimer::timeout触发的函数中逐个出列。

2 个答案:

答案 0 :(得分:3)

What's the difference between connecting the signal QTimer::timeout to my working 
function and creating a worker thread with QThread?

连接来自具有相同线程关联的对象的某些信号/插槽对时,则连接 direct 。这意味着在你的情况下,主线程创建timer,并且还包含slot,因此signal将在main线程中发出,也将在main线程中处理(因为插槽也在主线程中)。

连接来自具有不同线程关联的对象的某些信号/插槽对时,连接排队。这意味着信号发射插槽执行将在不同的线程中运行。

真正实现并发,定时器信号处理插槽在主线程中顺序执行。

所以这是您的选择:

  1. 如果要在主线程中处理数据,则当前代码正常。
  2. 如果要在主线程中发出timeout并在不同线程中处理数据,则使用处理方法创建新类,并将moveToThread 与该类的对象一起使用。
  3. 您提供的链接确实有不同的情况。在您的情况下(如果我错了,请纠正我),只有在数据可用时才处理数据,而不仅仅是在指定时间之后。您的情况很像传统的生产者/消费者问题。我的建议是根本不使用QTimer。而是使用class创建一个新的slot来处理数据。然后emit在数据可用时来自主线程的信号,并将if连接到处理slot。您将实现真正的并发。在这种情况下,您需要为共享数据访问实现锁定,在Qt中很容易,您只需使用QMutexLocker

答案 1 :(得分:2)

首先,一点背景:

threads背后的一个基本思想是,一个线程一次只能做一件事。它可能是更新GUI,处理数据或与远程服务器通信,但它不能一次完成所有这些事情。

这就是多线程的用武之地。你可能希望你的计算机一次做很多事情(观看视频,浏览网页,听音乐,同时编写代码)。计算机允许您通过在单独的线程上安排每个任务并定期在它们之间切换来实现这一点。

在过去,在多核处理器之前,这仅由multitasking实现(处理器将中断当前正在执行的线程,切换到另一个线程上下文并执行另一个线程一段时间再切换)。使用现代处理器,您可以在同一时间执行多个线程,每个核心一个。这通常称为multiprocessing

现在,回到你的问题:

线程一次只能做一件事,如果使用计时器,则使用主(AKA GUI)线程来处理数据。该线程通常负责响应OS事件和更新GUI(因此GUI线程)。如果您没有要处理的大量数据,通常可以在GUI线程上执行此操作。但是,如果数据处理时间有增长的可能性,建议在单独的线程上执行此类处理,以确保UI保持响应(以便您不会感到烦恼“您的程序没有响应”来自OS的消息)。基本上,如果数据处理时间超过200毫秒,建议在单独的线程上执行处理,以免用户觉得GUI“卡住”。