《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 里的数据并保存到文件
}

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

发布了40 篇原创文章 · 获赞 13 · 访问量 5890

猜你喜欢

转载自blog.csdn.net/weixin_42126427/article/details/104510581