QT线程二(线程的同步).docx_第1页
QT线程二(线程的同步).docx_第2页
QT线程二(线程的同步).docx_第3页
QT线程二(线程的同步).docx_第4页
QT线程二(线程的同步).docx_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

QT线程(二)-线程同步线程互斥多线程运行时,通常会访问同一个变量,同一个数据结构,或者同一段代码。因此,需要使用互斥技术来保护上述资源,确保多线程执行的正确性。注:我们通常说某个函数是线程安全的,也就是因为该函数实现加入了线程互斥保护。4.1、QMutexQMutex( RecursionModemode= NonRecursive )QMutex()voidlock()mutex加锁,如果当前其他线程已对该mutex加锁了,则该调用被阻塞直到其他线程释放该mutex。booltryLock()mutex加锁,和lock不同的是,如果当前其他线程已对该mutex加锁了,则该调用会立即返回,而不被阻塞。booltryLock( inttimeout)同tryLock,和tryLock不同的是,如果当前其他线程已对该mutex加锁了,则该调用会等待一段时间,直到超时或者其他线程释放了mutex。voidunlock()mutex解锁,释放被锁住的资源。Mutex有两种模式,用户可以在构造函数参数中指定。ConstantValueDescriptionQMutex:Recursive1In this mode, a thread can lock the same mutex multiple times and the mutex wont be unlocked until a corresponding number ofunlock() calls have been made.该模式下,一个线程可以对mutex多次lock,直到相应次数的unlock,调用后,该mutex才真正被unlock。QMutex:NonRecursive0In this mode, a thread may only lock a mutex once.该模式下,mutex只能被lock一次。实例:QMutex mutex; int number = 6; void method1() mutex.lock(); number *= 5; number /= 4; mutex.unlock(); void method2() mutex.lock(); number *= 3; number /= 2; mutex.unlock(); 4.1、QMutexLockerQMutexLocker( QMutex *mutex)QMutexLocker()QMutex *mutex() constvoidrelock()voidunlock()QMutexLocker实际上是对QMutex使用的一种简化。例如以下场景:当某段代码存在多个分支,在对QMutex加锁后,需要在不同的分支路径下都执行解锁操作,才能保证Mutex关联的资源能被其他线程继续访问,否则就出现死锁。QMutexLocker接收一个QMutex作为参数,当创建QMutexLocker对象时,就对关联的Mutex进行了Lock操作,直到该QMutexLocker对象被销毁,相关的QMutex才被Unlock。实例:直接使用QMutex:int complexFunction(int flag) mutex.lock(); int retVal = 0; switch (flag) case 0: case 1: mutex.unlock(); return moreComplexFunction(flag); case 2: int status = anotherFunction(); if (status 10) mutex.unlock(); return -1; break; mutex.unlock(); return retVal; 使用QMutexLocker:int complexFunction(int flag) QMutexLocker locker(&mutex); int retVal = 0; switch (flag) case 0: case 1: return moreComplexFunction(flag); case 2: int status = anotherFunction(); if (status 10) return -1; break; return retVal; 当然,使用QMutexLocker时,也需要注意QMutexLocker对象的生存周期,否则可能会出现锁时间过长,或者锁住的资源过多。4.3、QReadLocker、QWriteLocker、QReadWriteLocker还有一种场景,我们所保护的资源是具有读写权限的,多个线程可以同时读取某个资源,但是当存在写操作,写操作未完成时,就不允许其他线程对该资源进行读操作。QReadWriteLock()QReadWriteLock( RecursionModerecursionMode)QReadWriteLock()voidlockForRead()voidlockForWrite()booltryLockForRead()booltryLockForRead( inttimeout)booltryLockForWrite()booltryLockForWrite( inttimeout)voidunlock()QReadLocker( QReadWriteLock *lock)QReadLocker()QReadWriteLock *readWriteLock() constvoidrelock()voidunlock()QWriteLocker( QReadWriteLock *lock)QWriteLocker()QReadWriteLock *readWriteLock() constvoidrelock()voidunlock()实例:QReadWriteLock lock; void ReaderThread:run() . lock.lockForRead(); read_file(); lock.unlock(); . void WriterThread:run() . lock.lockForWrite(); write_file(); lock.unlock(); . 4.4、QSemaphore和QMutex不同的是,QSemaphore一次可以对多个资源进行保护,例如以下场景:某工厂只有固定仓位,生产人员每天生产的产品数量不一,销售人员每天销售的产品数量也不一致。当生产人员生产P个产品时,就一次需要P个仓位,当销售人员销售C个产品时,就要求仓库中有足够多的产品才能销售。如果剩余仓位没有P个时,该批次的产品都不存入,当当前已有的产品没有C个时,就不能销售C个以上的产品,直到新产品加入后方可销售。这就是典型的生产者-消费者问题。QSemaphore( intn= 0 )QSemaphore()voidacquire( intn= 1 )intavailable() constvoidrelease( intn= 1 )booltryAcquire( intn= 1 )booltryAcquire( intn, inttimeout)实例:QSemaphore sem(5); / sem.available() = 5 默认有5个产品 sem.acquire(3); / sem.available() = 2 销售3个产品,成功 sem.acquire(2); / sem.available() = 0 销售2个产品成功 sem.release(5); / sem.available() = 5 生产5个产品 sem.release(5); / sem.avail

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论