原文见http://qt-project.org/doc/qt-4.8/threads-starting.html
使用QThead进行线程开发
一个QThread实例代表一个线程并且提供了start()方法以启动线程,该线程随之将会执行覆写QThread::run()。run()之于线程,相当于main()之于应用,都是作为入口。所有在run()中的代码都为新的线程所执行,当run()函数返回时,线程就结束了。QThread发出信号指示线程的启动或结束。
创建线程:
以QThread作为基类声明其子类,并覆写run()方法,线程就创建好了
class MyThread : public QThread
{
Q_OBJECT
protected:
void run();
};
void MyThread::run()
{
...
}
class MyThread : public QThread
{
Q_OBJECT
protected:
void run();
};
void MyThread::run()
{
...
}
启动线程:
然后,创建一个线程对象的实例并调用QThread::start().注意你一定要在线程创建前首先创建QApplication (或QCoreApplication)对象这个函数将立即返回,主线程将继续运行。在run()中覆写的代码将会在另一个线程中执行。
QThread 文档中包含更多对于创建线程的解释。
注意 QCoreApplication::exec() 一定要在主线程中调用(那个执行main()的线程),而不能从QThread中执行。在图形用户界面中,主线程也被称为UI线程因为它是唯一被允许进行UI操作的线程。
线程同步:
QMutex, QReadWriteLock, QSemaphore,和QWaitCondition类提供了线程同步的方法。使用线程的本意是尽可能达到并发的效果,(但程序执行中)有些地方线程必须停下来等待其他线程。例如,如果两个线程同时刻试图访问同一全局变量,通常会造成不确定的结果。
QMutex 提供了一种手动lock,或互斥锁,任何时刻至多一个线程能获得互斥锁。如果一个线程尝试获得锁当互斥锁已经被上所。这个线程将会睡眠直到当前持有锁的线程解开锁。互斥锁通常用来保护共享数据(例如,能被多个线程同时访问的数据)的访问权限。在接下来的可重入和线程安全一节,我们将使用QMutex使得一个类线程安全。
QReadWriteLock 与QMutex相似,除了它将对共享数据的读与写权限区分开来,并且允许多个线程同时读数据。尽可能使用QReadWriteLock 代替QMutex将会使得多线程程序并发性更强。
QSemaphore 是QMutex 的实现,用来保护某些一系列等同的资源。而相反,mutex 只用来保护一个资源。Semaphores 例程展示了Semaphores 的典型程序:在生产者和消费者间同步流通的缓存的访问权限。
QWaitCondition 允许线程在某些条件满足时,将其余线程唤醒。一个或多个线程可以阻塞等待QWaitCondition设置的条件以wakeOne() or wakeAll()满足。使用wakeOne()可以随机选择一个线程唤醒,而使用wakeAll()将所有线程唤醒。
条件变量的例程展现了如何使用QWaitCondition 而非信号量去解决生产者-消费者问题。
注意Qt同步的类依赖严格对齐的指针的使用。比如,你不能使用MSVC包装类。