本程序中都是基于第13章第一个例子来改变的:
传送门:
首先我们来说下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 里的数据并保存到文件
}
这样变可以解决这个问题,让我们一起加油学习,提高自己的水平。