QT线程二线程的同步.docx
- 文档编号:11210155
- 上传时间:2023-02-25
- 格式:DOCX
- 页数:10
- 大小:32.66KB
QT线程二线程的同步.docx
《QT线程二线程的同步.docx》由会员分享,可在线阅读,更多相关《QT线程二线程的同步.docx(10页珍藏版)》请在冰豆网上搜索。
QT线程二线程的同步
QT线程二(线程的同步)
QT线程
(二)---线程同步
线程互斥
多线程运行时,通常会访问同一个变量,同一个数据结构,或者同一段代码。
因此,需要使用互斥技术来保护上述资源,确保多线程执行的正确性。
注:
我们通常说某个函数是线程安全的,也就是因为该函数实现加入了线程互斥保护。
4.1、QMutex
QMutex (RecursionMode mode =NonRecursive)
~QMutex ()
void
lock ()
mutex加锁,如果当前其他线程已对该mutex加锁了,则该调用被阻塞直到其他线程释放该mutex。
bool
tryLock ()
mutex加锁,和lock不同的是,如果当前其他线程已对该mutex加锁了,则该调用会立即返回,
而不被阻塞。
bool
tryLock (int timeout )
同tryLock,和tryLock不同的是,如果当前其他线程已对该mutex加锁了,则该调用会等待一段时间,
直到超时或者其他线程释放了mutex。
void
unlock ()
mutex解锁,释放被锁住的资源。
Mutex有两种模式,用户可以在构造函数参数中指定。
Constant
Value
Description
QMutex:
:
Recursive
1
Inthismode,athreadcanlockthesamemutexmultipletimesandthemutexwon'tbeunlockeduntilacorrespondingnumberof unlock()callshavebeenmade.
该模式下,一个线程可以对mutex多次lock,直到相应次数的unlock,调用后,该mutex才真正被unlock。
QMutex:
:
NonRecursive
0
Inthismode,athreadmayonlylockamutexonce.
该模式下,mutex只能被lock一次。
实例:
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:
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
还有一种场景,我们所保护的资源是具有读写权限的,多个线程可以同时读取某个资源,但是当存在写操作,写操作未完成时,就不允许其他线程对该资源进行读操作。
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 ()
实例:
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个以上的产品,直到新产品加入后方可销售。
这就是典型的生产者-消费者问题。
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 )
实例:
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个产品
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- QT 线程 同步