QT线程(二)---线程同步

 

线程互斥html

       多线程运行时,一般会访问同一个变量,同一个数据结构,或者同一段代码。所以,须要使用互斥技术来保护上述资源,确保多线程执行的正确性。安全

注:数据结构

咱们一般说某个函数是线程安全的,也就是由于该函数实现加入了线程互斥保护。多线程

 

 

       4.一、QMutex函数

 

QMutex ( RecursionMode mode = NonRecursive )ui

 

~QMutex ()this

void.net

lock ()线程

mutex加锁,若是当前其余线程已对该mutex加锁了,则该调用被阻塞直到其余线程释放该mutex。htm

bool

tryLock ()

mutex加锁,和lock不一样的是,若是当前其余线程已对该mutex加锁了,则该调用会当即返回,而不被阻塞。

bool

tryLock ( int timeout )

同tryLock,和tryLock不一样的是,若是当前其余线程已对该mutex加锁了,则该调用会等待一段时间,直到超时或者其余线程释放了mutex。

void

unlock ()

mutex解锁,释放被锁住的资源。

 

       Mutex有两种模式,用户能够在构造函数参数中指定。

      

Constant

Value

Description

QMutex::Recursive

1

In this mode, a thread can lock the same mutex multiple times and the mutex won't be unlocked until a corresponding number of unlock() calls have been made.

该模式下,一个线程能够对mutex屡次lock,直到相应次数的unlock,调用后,该mutex才真正被unlock。

QMutex::NonRecursive

0

In 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.一、QMutexLocker

 

 

QMutexLocker ( QMutex * mutex )

 

~QMutexLocker ()

QMutex *

mutex () const

void

relock ()

void

unlock ()

 

       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 < 0) {
                 mutex.unlock();
                 return -2;
             }
             retVal = status + flag;
         }
         break;
     default:
         if (flag > 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 < 0)
                 return -2;
             retVal = status + flag;
         }
         break;
     default:
         if (flag > 10)
             return -1;
         break;
     }
 
     return retVal;
 }

 

固然,使用QMutexLocker时,也须要注意QMutexLocker对象的生存周期,不然可能会出现锁时间过长,或者锁住的资源过多。

 

 

4.三、QReadLocker、QWriteLocker、QReadWriteLocker

       还有一种场景,咱们所保护的资源是具备读写权限的,多个线程能够同时读取某个资源,可是当存在写操做,写操做未完成时,就不容许其余线程对该资源进行读操做。

 

 

QReadWriteLock ()

 

QReadWriteLock ( RecursionMode recursionMode )

 

~QReadWriteLock ()

void

lockForRead ()

void

lockForWrite ()

bool

tryLockForRead ()

bool

tryLockForRead ( int timeout )

bool

tryLockForWrite ()

bool

tryLockForWrite ( int timeout )

void

unlock ()

 

 

 

QReadLocker ( QReadWriteLock * lock )

 

~QReadLocker ()

QReadWriteLock *

readWriteLock () const

void

relock ()

void

unlock ()

 

 

QWriteLocker ( QReadWriteLock * lock )

 

~QWriteLocker ()

QReadWriteLock *

readWriteLock () const

void

relock ()

void

unlock ()

 

实例:

QReadWriteLock lock;
 
 void ReaderThread::run()
 {
     ...
     lock.lockForRead();
     read_file();
     lock.unlock();
     ...
 }
 
 void WriterThread::run()
 {
     ...
     lock.lockForWrite();
     write_file();
     lock.unlock();
     ...
 }

 

4.四、QSemaphore

       和QMutex不一样的是,QSemaphore一次能够对多个资源进行保护,

例如如下场景:

       某工厂只有固定仓位,生产人员天天生产的产品数量不一,销售人员天天销售的产品数量也不一致。当生产人员生产P个产品时,就一次须要P个仓位,当销售人员销售C个产品时,就要求仓库中有足够多的产品才能销售。

若是剩余仓位没有P个时,该批次的产品都不存入,当当前已有的产品没有C个时,就不能销售C个以上的产品,直到新产品加入后方可销售。

       这就是典型的生产者-消费者问题。

 

 

QSemaphore ( int n = 0 )

 

~QSemaphore ()

void

acquire ( int n = 1 )

int

available () const

void

release ( int n = 1 )

bool

tryAcquire ( int n = 1 )

bool

tryAcquire ( int n, int timeout )

 

实例:

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.available() == 10 生产10个产品
 
 sem.tryAcquire(1);      // sem.available() == 9, returns true 消费1个产品,成功
 sem.tryAcquire(250);    // sem.available() == 9, returns false 企图销售250个产品,失败,由于当前只剩下14个产品

 

 

4.五、QWaitCondition

相关文章
相关标签/搜索