Qt中线程使用QThread类管理。使用QThread的方法是继承QThread,在QThread的子类中重新实现虚函数run(),run()函数体中的代码就是运行在一个新的线程中。要启动线程,只创建QThread对象还不够,还要调用对象的start()成员函数,它会导致run()的执行,start()不会阻塞,启动完线程函数run()后start()马上返回,然后线程便在运行了。QThread类只是用来管理操作系统的线程实体,但不是线程本身。
(注意:不可以在线程运行结束前销毁QThread对象)
每个线程都有自己栈,但线程之间共享地址空间,所以只要有另一个线程栈中变量的地址,就可以访问另一个线程函数中的局部变量,当然所有线程都可以访问全局变量。每个线程的程序计数器和一些寄存器的内容保存在内核内存空间中,用户空间是分离的栈区和共享的堆区。
class MyThread : public QThread { public: void run(); };
void MyThread::run()
{ //... }
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
//创建线程对象前一定要创建QApplication对象 MyThread mth;
mth.start(); //启动线程函数
mth.wait(); //wait()函数会阻塞直到run()函数执行结束 return 0; }
线程与事件循环:
每个线程都有自己的事件循环,在线程中创建的对象的事件,由此事件循环管理。所谓“在线程中创建“指的是在run()函数里创建,而QThread类的成员变量不是在run()的线程中创建的,而是在主线程中创建的: void MyThread::run() { }
QTimer* ptmr = new Qtimer; //在线程里创建 My my; //在线程里创建
connect(ptmr, SIGNAL(timeout()), &my, SLOT(tslot())); ptmr->start(1000);
exec(); //启动事件循环,他不会返回,直到quit()或exit()被调用
//本例中的QTimer定时功能就是由本线程自己的事件循环管理的
每个线程有自己的事件循环,主线程又叫GUI线程,只能在主线程中进行GUI相关的操作
? QThread对象并不是存在于run()函数所执行的新线程里,它存在(分配内
存)于创建它的旧线程里。
? 大多数QThread的成员函数,它们意在在旧线程调用,用于控制run()所执
行的线程的。
? 在QThread子类中定义的数据成员,是可以被旧线程和run()执行线程同时
访问的数据,可以使用互斥锁协调访问。典型性的策略是,主线程(旧线程)先设置这些变量,然后start(),运行run()线程,在run()线程运行的过程中,主线程不再去访问这些成员变量,直到run()退出,之后主线程可以再去访问这些成员变量,变量可以用于保存run()线程运行的结果。
由一个线程中的对象向另一个线程中的对象发信号
一种典型的使用线程的方式是,以一个GUI主线程为核心,同时存在若干个工作线程(worker thread),GUI线程可以向工作线程中的对象发信号,工作线程中的对象也可以像GUI线程中的对象发信号,同时主线程和工作线程可以通过在QThread子类定义成员变量,互通数据。
QThread 对象的其他常用函数
void setPriority ( Priority priority ) 设置run()线程优先级 void setStackSize ( uint stackSize ) 设置run()线程栈大小 void quit () 使run() 线程从exec()启动的事件循环中退出
void terminate () 退出run()线程,线程会中途退出,如果后面有互斥锁未解也不会处理,不建议使用。
QThread * QThread::currentThread () [static] 返回当前执行线程的QThread对象指针,静态成员函数。
线程同步
线程的同步常用对象有: QMutex 互斥锁 void lock () bool tryLock ()
bool tryLock ( int timeout ) void unlock ()
用于保护一段代码,变量或对象一次只被一个线程访问。 lock()取得锁,如果其他线程已经获得锁则阻塞 unlock()释放锁
trylock()尝试取得锁,如果其他线程已经获得锁则立即返回,返回值为false,若成功获得锁返回true QWaitCondition 条件变量
bool wait ( QMutex * mutex, unsigned long time = ULONG_MAX ) void wakeAll () void wakeOne ()
条件变量用于让一个线程告诉其他线程某个条件得到满足,在这个条件上阻塞等待的线程中的一个或所有会被从等待中唤醒,唤醒的线程数量取决于,用wakeAll()唤醒还是用wakeOne()唤醒。
wait()函数需要一个锁住状态的互斥锁为参数,等待时互斥锁解锁,wait()返回后互斥锁恢复锁住状态,如果wait()的互斥锁参数不是锁住状态,那么wait会立即返回。
相关推荐: