qmutexlocker的用法,看起来简洁,实际如此吗

Qt同步线程
我们知道,多线程有的时候是很有用的,但是在访问一些公共的资源或者数据时,需要进行同步,否则会使数据遭到破坏或者获取的值不正确。Qt提供了一些类来实现线程的同步,如,,,,,和。下面我们分别来看它们的用法:
首先,简单的了解一下QMutex提供的函数。
构造函数:QMutex&(&&mode&= NonRecursive )。
需要注意的是构造函数的参数,&递归模式。枚举类型&有两个值:
QMutex::Recursive,在这个模式下,一个线程可以多次锁同一个互斥量。需要注意的是,调用lock()多少次锁,就必须相应的调用unlock()一样次数解锁。
QMutex::NonRecursive(默认),在这个模式下,一个线程只能锁互斥量一次。
void&QMutex::lock&()
该函数用来锁住一个互斥量。如果另外的线程已经锁住了互斥量,函数将被阻塞等待另外的线程解锁互斥量。
如果是一个可递归的互斥量,则可以从同一个线程多次调用这个函数,如果是非递归的互斥量,多次调用这个函数将会引发死锁。我们来看看源码是怎么实现的。
void&QMutex::lock()
&&& QMutexPrivate *d =&static_cast&QMutexPrivate*&(this-&d);
&&& Qt::HANDLE
&&&&if(d-&recursive) {
&&&&&&& self = QThread::currentThreadId();
&&&&&&&&if(d-&owner == self) {
&&&&&&&&&&& ++d-&&&&&&&&&&&&& //同一个线程多次lock时,仅仅自增count
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //当然递归次数太多也会导致栈溢出
&&&&&&&&&&& Q_ASSERT_X(d-&count != 0,&"QMutex::lock",&"Overflowin recursion counter");
&&&&&&&&&&&&
&&&&&&&&boolisLocked = d-&contenders.testAndSetAcquire(0, 1);
&&&&&&&&if(!isLocked) {
&&&&&&&&&&&&// didn'tget the lock, wait for it
&&&&&&&&&&& isLocked = d-&wait();
&&&&&&&&&&& Q_ASSERT_X(isLocked,&"QMutex::lock",
&&&&&&&&&&&&&&&&&&&&&&&"Internalerror, infinite wait has timed out.");
&&&&&&& d-&owner =&&&&&&&&& //递归模式时,owner记录拥有互斥量的线程
&&&&&&& ++d-&&&&&&&&&&&&& //记录lock的次数
&&&&&&& Q_ASSERT_X(d-&count != 0,&"QMutex::lock",&"Overflowin recursion counter");
&&& //非递归模式时,
&&&&boolisLocked = d-&contenders.testAndSetAcquire(0, 1);&& //尝试加锁
&&&&if(!isLocked) {
&&&&&&& lockInternal();& //加锁失败则在lockInternal()中一直等到别的线程解锁。
看看lockInternal的实现
void&QMutex::lockInternal()
&&&&&&& 。。。。//其他代码太复杂,感觉最重要的就是这个while循环了,
&&&&&&&&&&&&&&& //一直循环检测,试图加锁。这我们就好理解,非递归模式的//互斥量,不要在同一个线程里,多次调用lock了。因为第二次调用的时候会在
//这里死循环了
&&& }&while(d-&contenders != 0 || !d-&contenders.testAndSetAcquire(0, 1));
。。。。。。。
bool&QMutex::tryLock&()
该函数试图锁一个互斥量,如果成功则返回true。如果另外的线程已经锁住了互斥量,函数直接返回false。
bool&QMutex::tryLock&(&int&timeout&)
该函数跟上面的trylock()相似。不同的是,如果互斥量在别的线程锁住的情况下,函数会等待timeout&毫秒。需要注意的是,如果传入的timeout&为负数,函数将无限期等待,跟调用lock()一样的效果。这个函数跟上面的差不多,所以只看该函数的源码实现就好了。
bool&QMutex::tryLock(inttimeout)
&&& QMutexPrivate *d =&static_cast&QMutexPrivate*&(this-&d);
&&&Qt::HANDLE
&&&&if(d-&recursive) {
&&&&&&& self = QThread::currentThreadId();
&&&&&&&&if(d-&owner == self) {
&&&&&&&&&&& ++d-&
&&&&&&&&&&& Q_ASSERT_X(d-&count != 0,&"QMutex::tryLock",&"Overflow in recursion counter");
&&&&&&&&&&&&
&&&&&&&&boolisLocked = d-&contenders.testAndSetAcquire(0, 1);
&&&&&&&&if(!isLocked) {
&&&&&&&&&&&&// didn'tget the lock, wait for it
&&&&&&&&&&& isLocked = d-&wait(timeout);&&& //尝试加锁失败则等待
&&&&&&&&&&&&if(!isLocked)
&&&&&&&&&&&&&&&&
&&&&&&& d-&owner =
&&&&&&& ++d-&
&&&&&&& Q_ASSERT_X(d-&count != 0,&"QMutex::tryLock",&"Overflow in recursion counter");
&&&&&&&&return&
//尝试加锁失败,(d-&contenders.testAndSetAcquire(0,1)返回false,所以继续执行d-&wait(timeout);
&&&&return&(d-&contenders.testAndSetAcquire(0, 1) ||d-&wait(timeout));
//在win下,wait函数实际上是用事件对象实现的
bool&QMutexPrivate::wait(inttimeout)
&&&&if(contenders.fetchAndAddAcquire(1) == 0) {
&&&&&&&&// lockacquired without waiting
&&&&&&&&return&
// 当timeout 小于0,则等待时间为INFINITE,这也就是为什么传负数参数时跟lock一样会无限期等待了
&&&&boolreturnValue = (WaitForSingleObject(event,timeout & 0 ?&INFINITE&: timeout) ==& WAIT_OBJECT_0);
&&& contenders.deref();
&&&&returnreturnV
void&QMutex::unlock&()
该函数对互斥量进行解锁。如果在另外的线程加锁,尝试在别的线程进行解锁则会引发错误。试图对没有加锁的互斥量解锁结果是未定义的。
QmutexLocker只是为了简化我们队互斥量的加锁和解锁操作。就像智能指针方便我们使用普通指针一样。
&(QMutex *&mutex&)。
构造函数必须传入一个互斥量指针,然后在构造函数里mutex直接调用lock()。
inline&explicitQMutexLocker(QMutex *m)
&&&&&&& Q_ASSERT_X((reinterpret_cast&quintptr&(m)& quintptr(1u)) == quintptr(0),
&&&&&&&&&&&&&&&&&&&"QMutexLocker","QMutex pointer is misaligned");
&&&&&&&&if&(m){
&&&&&&&&&&& m-&lockInline();&&& //&mutex调用lock()加锁
&&&&&&&&&&& val =&reinterpret_cast&quintptr&(m)| quintptr(1u);
&&&&&&& }&else{
&&&&&&&&&&& val = 0;
inline&~QMutexLocker() { unlock(); }
inline&void&unlock()
&&&&&&&&&&&&&&if((val & quintptr(1u)) == quintptr(1u)) {
&&&&&&&&&&&&&&&&&&&& val &= ~quintptr(1u);
&&&&&&&&&&&&&&&&&&&& mutex()-&unlockInline();&&&//析构时调用unlock,确保mutex在离开调用线程时被解锁。
&&&&&&&&&&&&& }
下面来看看具体的用法:
假设有个函数有很多return 语句,那么我们就必须记得在每个语句前unlock互斥量,否则互斥量将无法得到解锁,导致其他等待的线程无法继续执行。
int complexFunction(intflag)
&&&& mutex.lock();
&&&& int retVal = 0;
&&&& switch (flag) {
&&&& case 0:
&& &&case1:
&&&&&&&& retVal = moreComplexFunction(flag);
&&&& case 2:
&&&&&&&& {
&&&&&&&&&&&& int status = anotherFunction();
&&&&&&&&&&&& if (status & 0) {
&&&&&&&&&&&&&&&& mutex.unlock();
&&&&&&&&&&&&&&&& return -2;
&&&&&&&&&&&& }
&&&&&&&& &&&&retVal = status +
&&&&&&&& }
&&&& default:
&&&&&&&& if (flag & 10) {
&&&&&&&&&&&& mutex.unlock();
&&&&&&&&&&&& return -1;
&&&&&&&& }
&&&& mutex.unlock();
&&&& return retV
这样的代码显得很冗余又容易出错。如果我们用QMutexLocker
intcomplexFunction(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 +
&&&&&&&& }
&&&& default:
&&&&&&&& if (flag & 10)
&&&&&&&&&&&& return -1;
&&&& return retV
由于locker 是局部变量,在离开函数作用域时,mutex肯定会被解锁。
QreadWriteLock
QreadWriteLock是一个读写锁,主要用来同步保护需要读写的资源。当你想多个读线程可以同时读取资源,但是只能有一个写线程操作资源,而其他线程必须等待写线程完成时,这时候用这个读写锁就很有用了。QreadWriteLock也有递归和非递归模式之分。
我们主要来看看最重要的两个函数是如何实现读写操作的同步的。
void&QReadWriteLock::lockForRead&()
该函数lock接了读操作的锁。如果有别的线程已经对lock接了写操作的锁,则函数会阻塞等待。
void&QReadWriteLock::lockForRead()
&&& QMutexLocker lock(&d-&mutex);
&&& Qt::HANDLE self = 0;
&&&&if(d-&recursive) {
&&&&&&& self = QThread::currentThreadId();
&&&&&&& QHash&Qt::HANDLE,&int&::iterator it = d-&currentReaders.find(self);
&&&&&&&&if&(it!= d-&currentReaders.end()) {
&&&&&&&&&&& ++it.value();
&&&&&&&&&&& ++d-&accessC
&&&&&&&&&&& Q_ASSERT_X(d-&accessCount &0,&"QReadWriteLock::lockForRead()",
&&&&&&&&&&&&&&&&&&&&&&&"Overflowin lock counter");
&&&&&&&&&& &
// accessCount 小于0说明有写线程在操作资源,则阻塞
&&&&while(d-&accessCount & 0 || d-&waitingWriters) {
&&&&&&& ++d-&waitingR&&&&&&&&&&&& //自增等待的读线程数
&&&&&&&d-&readerWait.wait(&d-&mutex);
&&&&&&& --d-&waitingR
&&&&if(d-&recursive)
&&&&&&& d-&currentReaders.insert(self, 1);
&&& ++d-&accessC&&& //自增,记录有多少个线程访问了资源
&&& Q_ASSERT_X(d-&accessCount & 0,&"QReadWriteLock::lockForRead()",&"Overflow in lock counter");
void&QReadWriteLock::lockForWrite&()
该函数给lock加了写操作的锁,如果别的线程已经加了读或者写的锁,则函数会被阻塞。
void&QReadWriteLock::lockForWrite()
&&& QMutexLocker lock(&d-&mutex);
&&& Qt::HANDLE self = 0;
&&&&if(d-&recursive) {
&&&&&&& self = QThread::currentThreadId();
&&&&&&&&if(d-&currentWriter == self) {
&&&&&&&&&&& --d-&accessC
&&&&&&&&&&& Q_ASSERT_X(d-&accessCount &0,&"QReadWriteLock::lockForWrite()",
&&&&&&&&&&&&&&&&&&&&&&&"Overflowin lock counter");
&&&&&&&&&&&&
// accessCount不等于0,说明有线程在操作资源,则函数阻塞等待。
//&accessCount大于0说明有读线程在读取资源,&&
// accessCount小于0说明有写线程在写数据
&while(d-&accessCount != 0) {
&&&&&&& ++d-&waitingW&&&&&&& //自增等待的写线程数
&&&&&&&d-&writerWait.wait(&d-&mutex);
&&&&&&& --d-&waitingW
&&&&if(d-&recursive)
&&&&&&& d-&currentWriter =
&&& --d-&accessC
&&& Q_ASSERT_X(d-&accessCount & 0,&"QReadWriteLock::lockForWrite()",&"Overflow in lock counter");
void&QReadWriteLock::unlock&()
解锁函数,下面我们看看源码是如何实现,让等待的写线程优先于读线程获得互斥量的锁的。
void&QReadWriteLock::unlock()
&&& QMutexLocker lock(&d-&mutex);
&&& Q_ASSERT_X(d-&accessCount != 0,&"QReadWriteLock::unlock()",&"Cannot unlock an unlocked lock");
&&&&boolunlocked =&
&&&&if(d-&accessCount & 0) {
&&&&&&&&// releasinga read lock
&&&&&&&&if(d-&recursive) {
&&&&&&&&&&& Qt::HANDLE self =QThread::currentThreadId();
&&&&&&&&&&& QHash&Qt::HANDLE,&int&::iterator it =d-&currentReaders.find(self);
&&&&&&&&&&&&if(it != d-&currentReaders.end()) {
&&&&&&&&&&&&&&&&if(--it.value() &= 0)
&&&&&&&&&&&&&&&&&&&d-&currentReaders.erase(it);
&&&&&&&&&&& }
&&&&&&& // d-&accessCount& 说明没有线程在操作资源了unlocked为true
&&&&&&& unlocked = --d-&accessCount == 0;
}&else&if&(d-&accessCount & 0 &&++d-&accessCount == 0)
// d-&accessCount &0 说明有写线程在操作。则解锁unlocked =&
&&&&&&&&// released awrite lock
&&&&&&&&unlocked =&
&&&&&&& d-&currentWriter = 0;
&& //最重要的就是这里
&&&&if(unlocked) {
&&&&&&&&if(d-&waitingWriters) {&
&//如果有写线程在等待,则wake一个写线程。前面我们已经知道,写线程是只
//能有一个对资源进行操作的,所以就wakeone了。
&&&&&&&&&&& d-&writerWait.wakeOne();
&&&&&&& }&else&if&(d-&waitingReaders) {
//如果没有等待的写线程,则wake全部的读线程。因为读线程是可以多个对资源进行操作的。
&&&&&&&&&&& d-&readerWait.wakeAll();
下面是我自己简单的实现用例:
class&Lock:publicQObject
&&&&&&&Q_OBJECT
&&&&&& Lock();
&&&&&& ~Lock();
&&&&&&&voidStart();
&&&&&&&voidRead();
&&&&&&&voidWrite();
&&&&&&&voidReadThread1();
&&&&&&&voidReadThread2();
&&&&&&&voidWriteThread1();
&&&&&&&voidWriteThread2();
protected:
&&&&&& string strR
&&&&&& QReadWriteL&&&&//非&?递&IY归&&的&I?
Lock::Lock()
&&&&&& strResource =&"Hellworld ......";
Lock::~Lock()
void&Lock::Read()
&&&&&& cout&&"Readdata :"&&strResource&&
&&&&&& QEventL
&&&&&& QTimer::singleShot(2000,&loop,SLOT(quit()));&&&//为a了&?使&1得&I?停&&&留&?的&I?时&&&A间?长&&写&&效&&果?好?点&I?,&?暂Y停&&&2s
&&&&&& loop.exec();
void&Lock::Write()
&&&&&& strResource =&"writelock ";
&&&&&& cout&&"Writedata :"&&strResource&&
&&&&&& QEventL
&&&& QTimer::singleShot(2000,&loop,SLOT(quit()));&&//为a了&?使&1得&I?停&&&留&?的&I?时&&&A间?长&&写&&效&&果?好?点&I?,&?暂Y停&&&2s
&&&&&& loop.exec();
void&Lock::ReadThread1()
&&&&&& lock.lockForRead();
&&&&&& cout&&"ReadThread1& lockForRead"&&
&&&&&& Read();
&&&&&& cout&&"ReadThread1& unlock"&&
&&&&&& lock.unlock();
void&Lock::ReadThread2()
&&&&&& lock.lockForRead();
&&&&&& cout&&"ReadThread2& lockForRead"&&
&&&&&& Read();
&&&&&& cout&&"ReadThread2& unlock"&&
&&&&&& lock.unlock();
void&Lock::WriteThread1()
&&&&&& lock.lockForWrite();
&&&&&& cout&&"WriteThread1& lockForWrite"&&
&&&&&& Write();
&&&&&& cout&&"WriteThread1& unlock"&&
&&&&&& lock.unlock();
void&Lock::WriteThread2()
&&&&&& lock.lockForWrite();
&&&&&& cout&&"WriteThread2& lockForWrite"&&
&&&&&& Write();
&&&&&& cout&&"WriteThread2& unlock"&&
&&&&&& lock.unlock();
void&Lock::Start()
&&&&&& QtConcurrent::run(this,&Lock::ReadThread1);
&&&&&& QtConcurrent::run(this,&Lock::ReadThread2);
&&&&&& QtConcurrent::run(this,&Lock::WriteThread1);
&&&&&& QtConcurrent::run(this,&Lock::WriteThread2);
这里我先启动两个读线程,再启动写线程,运行结果如下。我们发现先读线程1先加了锁,读线程1还没解锁的时候,读线程2已经加了锁,验证了读线程是可以同时进入的。
如果我改一下代码:
void&Lock::Start()
&&&&&& QtConcurrent::run(this,&Lock::WriteThread1);
&&&&&& QtConcurrent::run(this,&Lock::ReadThread1);
&&&&&& QtConcurrent::run(this,&Lock::ReadThread2);
&&&&&& QtConcurrent::run(this,&Lock::WriteThread2);
我先启动WriteThread1,然后启动两个读线程,最后启动WriteThread2。运行结果如下,我们发现,WriteThread1运行完之后,先运行WriteThread2,最后才是两个读线程。验证了写线程比读线程先获得锁。
QSemaphore
QSemaphore是提供一个计数的信号量。信号量是泛化的互斥量。一个信号量只能锁一次,但是我们可以多次获得信号量。信号量可以用来同步保护一定数量的资源。
信号量支持两个基本是函数,&()和&():
acquire(n)&:尝试获取n个资源。如果没有足够的可用资源,该函数调用会被则是。
release(n)&:释放n个资源。
它们的源码实现也很简单:
void&QSemaphore::acquire(intn)
&&& Q_ASSERT_X(n &= 0,&"QSemaphore::acquire",&"parameter 'n' must be non-negative");
&&& QMutexLocker locker(&d-&mutex);
&&&&while&(n& d-&avail)& //申请的资源n 大于可用资源avail则进入等待。
&&&&&&& d-&cond.wait(locker.mutex());&
&&& d-&avail -=
void&QSemaphore::release(intn)
&&& Q_ASSERT_X(n &= 0,&"QSemaphore::release",&"parameter 'n' must be non-negative");
&&& QMutexLocker locker(&d-&mutex);
&&& d-&avail +=
&&& d-&cond.wakeAll();
由于avail变量,实际就是一个int的计数变量 。所以我们在调用release()传入的参数n大于信号量初始值也没关系,只是说明可用资源增加了。
例如以下代码:
int&main(int&argc,&char&*argv[])
&&&&&& QCoreApplication a(argc, argv);
&&&&&& QSemaphore sem(5);
&&&&&& sem.acquire(5);&&&&&&&&
&&&&&& cout&&"acquire(5);& "&&"remaindresource :"&&sem.available()&&
&&&&&& sem.release(5);
&&&&&& cout&&"release(5)& "&&"remaindresource :"&&sem.available()&&
&&&&&& sem.release(10);
&&&&&& cout&&"release(10)& "&&"remaindresource :"&&sem.available()&&
&&&&&& sem.acquire(15);
&&&&&& cout&&"acquire(15);& "&&"remaindresource :"&&sem.available()&&
&&&&&&&returna.exec();
信号量最著名的就是生产者与消费者的例子,以后再研究了。
QWaitCondition类提供了一个条件变量,它允许我们通知其他线程,等待的某些条件已经满足。等待QWaitCondition变量的可以是一个或多个线程。当我们用()通知其他线程时,系统会随机的选中一个等待进行唤醒,让它继续运行。其实前面的信号量和读写锁内部实现都有用到QWaitCondition的。
下面我们来看这个类重要的几个函数:
ool&QWaitCondition::wait&(&&*&mutex,&unsigned&long&time&=ULONG_MAX )
该函数对mutex解锁,然后等待。在调用这个函数之前,mutex必须是加锁状态。如果mutex没有加锁,则函数直接返回。如果mutex是可递归的,函数也直接返回。该函数对mutex解锁,然后等待,知道以下条件之一满足:
1.&&&&&另外的线程调用()或&(),则该函数会返回true。
2.&&&&&时间过了Time毫秒。如果time为ULONG_MAX(默认),则将会一直等待不会超时。如果超时则返回false。
bool&QWaitCondition::wait&(&&*&readWriteLock,&unsigned&long&time&=ULONG_MAX )
函数对readWriteLock解锁并等待条件变量。在调用这个函数之前,readWriteLock必须是加锁状态的。如果不是加锁状态,则函数立即返回。readWriteLock必须不能是递归加锁的,否则将不能正确的解锁。返回的满足条件跟上面的函数一样。
http://blog.csdn.net/hai/article/details/9889123
Views(...) Comments()前几天在博客园看到一篇文章/kex1n/archive//2133389.html,里面吧mutex作为一个静态成员放入一个自定义的类里。在类创生之时调用lock,类析构之时unlock。只要在关键的代码段建立一个类的实例即可,省去了手动写lock-unlock的麻烦,也降低了忘记写unlock的风险。这个办法的巧妙在于利用了静态成员:不管有多少类的实例,静态成员在内存里只有一个。
今天尝试用QT的QMutex模仿他的代码,结果碰到了问题。编译总是不通过。后来在一个国外的网站上找到了答案:在含有mutex的类的cpp文件里,必须包含
QMutex lock::mutex;
下面上代码:
lock.h和 lock.cpp这两个是包含了QMutex静态成员的类的文件
#ifndef LOCK_H
#define LOCK_H
#include &qmutex.h&
class lock
#endif // LOCK_H
#include &lock.h&
#include &QDebug&
QMutex lock:://这句必须存在!!!
lock::lock()
qDebug()&&&about to lock&;
mutex.lock();
qDebug()&&&locked&;
lock::~lock()
mutex.unlock();
qDebug()&&&release&;
然后是两个竞争的线程:这2个线程其实一模一样,都属于同一个类thd
先看头文件:
#ifndef THREAD_H
#define THREAD_H
#include &QThread&
#include &QWidget&
class thd : public QThread
explicit thd(QWidget *, QObject *parent = 0);
public slots:
protected:
#endif // THREAD_H
然后是cpp:
#include &thread.h&
#include &lock.h&
#include &mainwindow.h&
#include &QDebug&
thd::thd(QWidget * p, QObject *parent) : QThread(parent)
thd::~thd()
if(isRunning())
terminate();
void thd::run()
qDebug()&&&thread output = &&&currentThreadId();
MainWindow * p = (MainWindow *)m_p;
p-&vPrintId();
最后是包含这两个线程的主窗体,双击它,就会启动这两个线程:
先看头文件:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include &QMainWindow&
#include &QMouseEvent&
#include &thread.h&
class MainWindow : public QMainWindow
MainWindow(QWidget *parent = 0);
~MainWindow();
vPrintId();
protected:
mouseDoubleClickEvent(QMouseEvent *);
#endif // MAINWINDOW_H
#include &mainwindow.h&
#include &QThread&
#include &QDebug&
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
m_pTh1 = new thd(this);
m_pTh2 = new thd(this);
MainWindow::~MainWindow()
delete m_pTh1;
delete m_pTh2;
void MainWindow::vPrintId()
qDebug()&&&window output = &&&QThread::currentThreadId()&&&\n&;
void MainWindow::mouseDoubleClickEvent(QMouseEvent *e)
m_pTh1-&start();
m_pTh2-&start();
启动后,发现程序顺序输出如下:
显然,一个线程被锁住,另一个就必须等待,说明线程很好的同步了。
最后一点要说明。其实这个静态变量也可以拿到lock.cpp的文件开头,而不必成为lock类的成员。起到的效果应该是一样的。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:11087次
排名:千里之外
原创:39篇
(1)(2)(10)(1)(1)(3)(9)(5)(2)(1)(1)(1)(1)(1)(2)(2)(1)(1)QMutex的用法,看起来简洁,实际如此吗 _ 哈尔滨商铺电子平台
QMutex的用法,看起来简洁,实际如此吗
你可以直接继承QThread类并实现它的run方法就可以了class Worker_1 ;&#47.start().start(); test main functionint main(void){
w2,你建议你使用共享内存的方式在Qt里面是QThread吧;
w2,当然如果情况还好: QObject{
protected,如果这个QbyteArray非常大的话,如果是多线程要在一个类里面也没啥问题,如果你涉及到多线程共享资源的访问的话两个线程间传递QByteArray:
virtual void run() {
Worker_1():
void start()
w1.;;&#47、QSemphore只可以用来做线程间同步;}在Qt里面QM}/ do somthing }}class Work_2
w1:sleep(300000):;
~Worker_1().start();你同样可以写出Work_2这个类class WorkM
public...: public QThread{
public,在Qt里面,效率那主要就是考虑你线程干什么工作了
被定时器中断也是一个可能。请检查。另外锁Mutex在等待的时候目测是里边你想销毁另外一个线程里的定时器造成的
在Qt里面是QThread吧,如果是多线程要在一个类里面也没啥问题,效率那主要就是考虑你线程干什么工作了,在Qt里面,你可以直接继承QThread类并实现它的run方法就可以了 class Worker_1 : public QThread { public: Worker_1(); ~Worker_1(); prot...
目测是里边你想销毁另外一个线程里的定时器造成的。请检查。 另外锁Mutex在等待的时候,被定时器中断也是一个可能。
返回主页:
本文网址:/view-.html}

我要回帖

更多关于 qmutex 用法 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信