全部博文(19)
分类: C/C++
2011-09-21 10:36:58
/************************************华丽丽的分割线*************************************/ 这篇文章和以下的一篇文章 QT中的多线程(二)皆为转载文章,文章转自: http://www.cppblog.com/yuanyajie/archive/2007/08/22/30599.html 十分感谢原文作者,帮我解决了近几日的疑惑,对于QT的线程间的通信有了进一步了解,在这里向他致以我崇高的敬意。 /************************************华丽丽的分割 线*************************************/ QT通过三种形式提供了对线程的支持。它们分别是,一、平台无关 的线程类,二、线程安全的事件投递,三、跨线程的信号-槽连接。这使得开发轻巧的多线程Qt程序更为容易, 并能充分利用多处理器机器的优势。多线程编程也是一个有用的模式,它用于解决执行较长时间的操作而不至于用户界面失去响应。在Qt的早期版本中,在构建库 时有不选择线程支持的选项,从4.0开始,线程总是有效的。 线 程类 Qt 包含下面一些线程相关的类: QThread 提供了开始一个新线程的方法 QThreadStorage 提供逐线程数据存储 QMutex 提供相互排斥的锁,或互斥量 QMutexLocker 是一个便利类,它可以自动对QMutex加锁与解锁 QReadWriterLock 提供了一个可以同时读操作的锁 QReadLocker与QWriteLocker 是便利类,它自动对QReadWriteLock加锁与解锁 QSemaphore 提供了一个整型信号量,是互斥量的泛化 QWaitCondition 提供了一种方法,使得线程可以在被另外线程唤醒之前一直休眠。 创建一个线程 为创建一个线程,子类化QThread并且重写它的run()函数,例如: class MyThread : public QThread { Q_OBJECT protected: void MyThread::run() 线程同步 void WriterThread::run() QSemaphore 是QMutex的一般化,它可以保护一定数量的相同资源,与此相对,一个 mutex只保护一个资源。下面例子中,使用QSemaphore来 控制对环状缓冲的访问,此缓冲区被生产者线程和消费者线程共享。生产者不断向缓冲写入数据直到缓冲末端,再从头开始。消费者从缓冲不断读取数据。信号量比 互斥量有更好的并发性,假如我们用互斥量来控制对缓冲的访问,那么生产者,消费者不能同时访问缓冲。然而,我们知道在同一时刻,不同线程访问缓冲的不同部 分并没有什么危害。 const int DataSize = 100000; QSemaphore freeBytes(BufferSize); class Producer : public QThread void Producer::run() class Consumer : public QThread void Consumer::run() int main(int argc, char *argv[]) 下面的例子中,生产者首先必须检查缓冲是否已满(numUsedBytes==BufferSize),如果是,线程停下来等待 bufferNotFull条件。如果不是,在缓冲中生产数据,增加numUsedBytes,激活条件 bufferNotEmpty。使用mutex来保护对numUsedBytes的访问。另外,QWaitCondition::wait()接收一个mutex作为参数,这个mutex应该被调用 线程初始化为锁定状态。在线程进入休眠状态之前,mutex会被解锁。而当线程被唤醒时,mutex会处于锁定状态,而且,从锁定状态到等待状态的转换是 原子操作,这阻止了竞争条件的产生。当程序开始运行时,只有生产者可以工作。消费者被阻塞等待bufferNotEmpty条件,一旦生产者在缓冲中放入 一个字节,bufferNotEmpty条件被激发,消费者线程于是被唤醒。 const int DataSize = 100000; QWaitCondition bufferNotEmpty; class Producer : public QThread void Producer::run() for (int i = 0; i < DataSize; ++i) { buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4]; mutex.lock(); class Consumer : public QThread void Consumer::run() fprintf(stderr, "%c", buffer[i % BufferSize]); mutex.lock(); int main(int argc, char *argv[]) |