《QT5.9 c++ 开发指南》第13章 QThread 中 QMutexLocker 与 QReadWritelock

本程序中都是基于第13章第一个例子来改变的:

传送门:

           QMutex 利用互斥锁

           QThread 的基本用法

首先我们来说下QMutexLocker 的基本用法吧,其实就是替换 QMutex 中的lock   unlock

我们常写成:

void QDiceThread::run()
{
    //线程任务
    m_stop = false; //启动线程 m_stop=false
    m_seq = 0; //掷骰子次数
    qsrand(uint(QTime::currentTime().msec())); //随机数初始化,qsrand是线程安全的
    while (!m_stop) {
        if(!m_Paused)
        {
            mutex.lock();
            m_diceValue = qrand(); //获取随机数
            m_diceValue = (m_diceValue % 6) +1;
            m_seq++;
            mutex.unlock();
        }
        msleep(500); //线程休眠500ms
    }
 
    //  在  m_stop==true时结束线程任务
    quit(); //相当于  exit(0),退出线程的事件循环
}

使用 QMutexLocker 写为

void QDiceThread::run()
{
    //线程任务
    m_stop = false; //启动线程 m_stop=false
    m_seq = 0; //掷骰子次数
    qsrand(uint(QTime::currentTime().msec())); //随机数初始化,qsrand是线程安全的
    while (!m_stop) {
        if(!m_Paused)
        {
            QMutexLocker Locker (&mutex) ;
            m_diceValue = qrand(); //获取随机数
            m_diceValue = (m_diceValue % 6) +1;
            m_seq++;
           
        }
        msleep(500); //线程休眠500ms
    }
 
    //  在  m_stop==true时结束线程任务
    quit(); //相当于  exit(0),退出线程的事件循环
}

       QMutexLocker 是另外一个简化 了互斥量处 理的类。 QMutexLocker 的构造函数接受一个互斥量作为参数井将其锁定 , QMutexLocker 的析构 函数则将此互斥量解锁,所 以在 QMutexLocker 实例变量的生存期内的代码段得到保护, 自动进行互斥量的锁定和解锁 。
 

项目连接:  工程13_3   提取码:p1x1

下面来看一下QReadWritelock 

• lockForRead(),以只读方式锁定资源,如果有其他线程以写入方式锁定,这个函数会阻塞;
• lockForWrite(),以写入方式锁定资源 ,如果本线程或其他线程以读或写模式锁定资源,这个函数就阻塞 ;
• unlock(), 解锁:
• tryLockForRead(), 是 lockForRead()的非阻塞版本 ;
• tryLockForWrite(), 是 lockForWrite()的非阻塞版本。

这个函数是为了解决下面的问题:

int buffer[lOO] ;
QMutex mutex ;
void threadDAQ : : run( )
{
   mutex.lock();
   get_data_and_write_in_buffer () ; //数据写入 buffer
   mutex.unlock();
}

void threadShow : : run ()
{
  mutex.lock();
  show_buffer (); //读取 buffer 里的数据并显示
  mutex.unlock() ;
}
void threadSaveFile :: run ()
{
  mutex.lock();
  Save_buffer_to_File () ; //读取 buffer 里的数据并保存到文件
  mutex.unlock();
}

这样写的话就会只能同时使用一个线程,但是保存与读数据可以同时进行,然后我们可以这样去改写:

int buffer[lOO] ;
QReadWriteLock Lock ;
void threadDAQ : : run()
{
   Lock.lockForWrite ();
   get_data_and_write_in_buffer () ; //数据写入 buffer
   Lock.unlock();
}

void threadShow : : run ()
{
  Lock.lockForRead() ;
  show_buffer (); //读取 buffer 里的数据并显示
  Lock.unlock();
}
void threadSaveFile :: run ()
{
  Lock.lockForRead() ;
  Save_buffer_to_File () ; //读取 buffer 里的数据并保存到文件
  Lock.unlock();
}

      这样,如果 threadDAQ 没有以 lockForWrite()锁定 Lock, threadShow 和 threadSaveFile 可以同时访问 buffer,否则 threadShow 和 threadSaveFile 都被阻塞 ;如果 threadShow 和 threadSaveFile 都没有锁定 ,那么 threadDAQ 能以写入方式锁定,否则 threadDAQ 就被阻塞。

       QReadLocker 和 QWriteLocker 是 QReadWriteLock 的简便形式,如同 QMutexLock1巳r 是 QMutex 的简便版本一样,无需与 tmlock()自己对使用 。 使用 QReadLocker 和 QWriteLocker,则上面的代码改写为:

int buffer[lOO] ;
QReadWriteLock Lock ;
void threadDAQ : : run()
{
   QWriteLocker Locker(&Lock) ;
   get_data_and_write_in_buffer () ; //数据写入 buffer
   
}

void threadShow : : run ()
{
  QReadLocker Locker (&Lock) ;
  show_buffer (); //读取 buffer 里的数据并显示

}
void threadSaveFile :: run ()
{
  QReadLocker Locker (&Lock) ;
  Save_buffer_to_File () ; //读取 buffer 里的数据并保存到文件
}

这样变可以解决这个问题,让我们一起加油学习,提高自己的水平。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值