Learning Qt 5! (19):线程

看完进程看线程,该部分待学习了操作系统之后要再看。
Qt 学习之路 2(71):线程简介(在开启新的线程之前,程序会被阻塞,甚至点击关闭时会提示没有响应;开启新的线程后就不会阻塞了)
Qt 学习之路 2(72):线程和事件循环
Qt 学习之路 2(73):Qt 线程相关类
Qt 学习之路 2(74):线程和 QObject
Qt 学习之路 2(75):线程总结

先了解一下线程和进程的区别,看知乎吧。
Qt 使用QThread 来管理线程。
在学习如何“正确”编写多线程程序前,再来了解两个概念:

1.可重入的(Reentrant):如果多个线程可以在同一时刻调用一个类的所有函数,并且保证每一次函数调用都引用一个唯一的数据,就称这个类是可重入的(Reentrant means that all the functions in the referenced class can be called simultaneously by multiple threads, provided that each invocation of the functions reference unique data.)。大多数 C++ 类都是可重入的。类似的,一个函数被称为可重入的,如果该函数允许多个线程在同一时刻调用,而每一次的调用都只能使用其独有的数据。全局变量就不是函数独有的数据,而是共享的。换句话说,这意味着类或者函数的使用者必须使用某种额外的机制(比如锁)来控制对对象的实例或共享数据的序列化访问。
2.线程安全(Thread-safe):如果多个线程可以在同一时刻调用一个类的所有函数,即使每一次函数调用都引用一个共享的数据,就说这个类是线程安全的(Threadsafe means that all the functions in the referenced class can be called simultaneously by multiple threads even when each invocation references shared data.)。如果多个线程可以在同一时刻访问函数的共享数据,就称这个函数是线程安全的。

然后要知道事件循环的概念。事件循环的伪代码描述大致如下所示:

while (is_active)
{
    while (!event_queue_is_empty) {
        dispatch_next_event();
    }
    wait_for_more_events();
}

我们不可能避免业务逻辑中的耗时操作,那么怎样做才能既可以执行那些耗时的操作,又不会阻塞事件循环呢?一般会有三种解决方案:

1.将任务移到另外的线程。
2.动强制运行事件循环。想要强制运行事件循环,需要在耗时的任务中一遍遍地调用QCoreApplication::processEvents()函数。QCoreApplication::processEvents()函数会发出事件队列中的所有事件,并且立即返回到调用者。在这里所做的,就是模拟了一个事件循环。
3.使用QEventLoop类重新进入新的事件循环。通过调用QEventLoop::exec()函数,重新进入新的事件循环,给QEventLoop::quit()槽函数发送信号则退出这个事件循环。

Qt中用于支持线程的类有三个:QThread、QRunnable和QtConcurrent。

什么时候应该使用线程呢?
1.当你不得不使用同步 API 的时候。
2.当你希望扩展到多核应用的时候。
3.当你不想被别人阻塞的时候。

什么时候不该使用线程呢?
1.定时器。
2.网络/状态机。
3.将任务分割成若干部分。

猜你喜欢

转载自blog.csdn.net/u013213111/article/details/86437096