您的位置:首页 > 编程语言 > Qt开发

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

2013-06-04 14:08 197 查看
转自:/article/9396444.html

线程互斥

多线程运行时,通常会访问同一个变量,同一个数据结构,或者同一段代码。因此,需要使用互斥技术来保护上述资源,确保多线程执行的正确性。
注:
我们通常说某个函数是线程安全的,也就是因为该函数实现加入了线程互斥保护。

4.1、QMutex

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

实例:

QMutexmutex;

intnumber=6;


voidmethod1()

{

mutex.lock();

number*=5;

number/=4;

mutex.unlock();

}


voidmethod2()

{

mutex.lock();

number*=3;

number/=2;

mutex.unlock();

}


4.1、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:

intcomplexFunction(intflag)

{

mutex.lock();


intretVal=0;


switch(flag){

case0:

case1:

mutex.unlock();

returnmoreComplexFunction(flag);

case2:

{

intstatus=anotherFunction();

if(status<0){

mutex.unlock();

return-2;

}

retVal=status+flag;

}

break;

default:

if(flag>10){

mutex.unlock();

return-1;

}

break;

}


mutex.unlock();

returnretVal;

}


使用QMutexLocker:

intcomplexFunction(intflag)

{

QMutexLockerlocker(&mutex);


intretVal=0;


switch(flag){

case0:

case1:

returnmoreComplexFunction(flag);

case2:

{

intstatus=anotherFunction();

if(status<0)

return-2;

retVal=status+flag;

}

break;

default:

if(flag>10)

return-1;

break;

}


returnretVal;

}


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

4.3、QReadLocker、QWriteLocker、QReadWriteLocker

还有一种场景,我们所保护的资源是具有读写权限的,多个线程可以同时读取某个资源,但是当存在写操作,写操作未完成时,就不允许其他线程对该资源进行读操作。

实例:

QReadWriteLocklock;


voidReaderThread::run()

{

...

lock.lockForRead();

read_file();

lock.unlock();

...

}


voidWriterThread::run()

{

...

lock.lockForWrite();

write_file();

lock.unlock();

...

}


4.4、QSemaphore

和QMutex不同的是,QSemaphore一次可以对多个资源进行保护,
例如以下场景:

某工厂只有固定仓位,生产人员每天生产的产品数量不一,销售人员每天销售的产品数量也不一致。当生产人员生产P个产品时,就一次需要P个仓位,当销售人员销售C个产品时,就要求仓库中有足够多的产品才能销售。
如果剩余仓位没有P个时,该批次的产品都不存入,当当前已有的产品没有C个时,就不能销售C个以上的产品,直到新产品加入后方可销售。

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

实例:

QSemaphoresem(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,returnstrue消费1个产品,成功

sem.tryAcquire(250);//sem.available()==9,returnsfalse企图销售250个产品,失败,因为当前只剩下14个产品
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: