Qt多线程同步

1、QMutex


 

QMutex mutex;

void func()

{

mutex.lock();

........

mutex.unlock();

}

2、QMutex联手QMutexLocker

在复杂函数或者异常处理中,对mutex进行lock()和unlock()操作将会很复杂,进入点要lock(),在所有跳出点都要unlock(),想想都蛋疼!忘记unlock()将是很苦逼的事情,所以Qt引进了QMutexLocker来避免lock()和unlock()操作。

QMutex mutex;

void complexFunc()

{

QMutexLocker locker(&mutex);//在函数需要的地方建立QMutexLocker对象,并把mutex指针传进来就好了,后面什么事情也不用做了,等到退出函数后,这个QMutexLocker对象局部变量会自己销毁,销毁了就解锁了。方便吧。当然,你也可以调用locker.unlock()给mutex解锁,然后再调用locker.relock()再锁住mutex。也可以调用locker.mutex()获取建立locker时引入的那个mutex的指针。是不是很方便?

..........

        ............

}

 

3、QReadWriteLock

这个允许多个进程同时读,但是只有一个写。而且写读不能同时进行。

QReadWriteLock lock;

void write()

{

lock.lockForWrite();//为写而锁

..........

lock.unlock();//解锁

}



void read()

{

lock.lockForRead();//为读而锁

..............

lock.unlock();//解锁

}

 

4、QReadWriteLock联手QReadLocker和QWriteLocker

 

这个有点类似于QMutex和QMutexLocker。也是为了避免那些复杂的lockForRead()/lockForWrite()和unlock()操作,要是程序流程复杂起来实在是很让人小心谨慎到蛋疼。但是联手QReadLocker和QWriteLocker后就不一样了。

QReadWriteLock lock;
void write()

{

QReadLocker locker(&lock);

..........

}


void read()

{

QWriteLocker locker(&lock);

..............

}

 

QReadLocker和QWriteLocker的成员函数都一模一样,退出函数的时局部变量locker会自动销毁,讲lock自动解锁。也可以调用locker.unlock()给lock解锁,然后再调用locker.relock()再锁住lock。也可以调用locker.readWriteLock()获取建立locker时引入的那个lock的指针。

 

5、QSemaphore

 

它的成员函数是

QSemaphore ( int n = 0 )//建立对象时可以给它n个资源

~QSemaphore ()

void acquire ( int n = 1 )// 这个操作一次减少n个资源,如果现有资源不到n个就会阻塞

int available () const   //返回当前可用的QSemaphore资源个数

void release ( int n = 1 )//这个操作一次增加n个资源

bool tryAcquire ( int n = 1 )//类似于acquire,但是申请不到n个资源时不会阻塞会立即返回

bool tryAcquire ( int n, int timeout )

下面举生产者-消费者例子说明

 

 const int DataSize = 100000;//要生产的数据个数

 const int BufferSize = 8192;//用于盛数据的缓存大小

 char buffer[BufferSize];

 

//要定义两个信号量,一个用于表示自由空间,一个用于表示已用空间

 QSemaphore freeBytes(BufferSize);//自由空间初始化大小当然等于缓存大小啦

 QSemaphore usedBytes;


class Producer : public QThread

 {

 public:

     void run();

 };



 void Producer::run()

 {

     qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));

     for (int i = 0; i < DataSize; ++i) {

         freeBytes.acquire();//申请一个自由空间,没有就阻塞

         buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4];

         usedBytes.release();//已用空间增加一个,有货啦!

     }

 }



class Consumer : public QThread

 {

 public:

     void run();

 };



 void Consumer::run()

 {

     for (int i = 0; i < DataSize; ++i) {

         usedBytes.acquire();

         fprintf(stderr, "%c", buffer[i % BufferSize]);

         freeBytes.release();

     }

     fprintf(stderr, "\n");

 }

int main(int argc, char *argv[])

 {

     QCoreApplication app(argc, argv);

     Producer producer;

     Consumer consumer;

     producer.start();

     consumer.start();

     producer.wait();

     consumer.wait();

     return 0;

 }

 

6、QWaitCondition

 

QWaitCondition最大的好处,我觉得,是能在一个线程中唤醒一个或多个其它线程,当然前提是,其它线程在等待某个QWaitCondition,否则不起作用,你唤醒也没用。QWaitCondition必须与QMutex或者QReadwriteLock一起用。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值