赞
踩
QThread类提供了管理线程的方法:
#ifndef DICETHREAD_H
#define DICETHREAD_H
#include <QThread>
class DiceThread : public QThread
{
Q_OBJECT
private:
int m_seq = 0;
int m_diceValue;
bool m_Paused = true;
bool m_stop = false;
public:
explicit DiceThread();
void diceBegin();
void dicePause();
void stopThread();
protected:
void run() Q_DECL_OVERRIDE;
signals:
void newValued(int seq, int diceValue);
public slots:
};
#endif // DICETHREAD_H
#include "dicethread.h"
#include <QTime>
DiceThread::DiceThread()
{
}
void DiceThread::diceBegin()
{
m_Paused = false;
}
void DiceThread::dicePause()
{
m_Paused = true;
}
void DiceThread::stopThread()
{
m_stop = true;
}
void DiceThread::run()
{
m_stop = false;
m_seq = 0;
qsrand(QTime::currentTime().second());
while (!m_stop) {
if(!m_Paused)
{
m_diceValue = qrand()%6+1;
m_seq++;
emit newValued(m_seq, m_diceValue);
}
sleep(1);
}
quit();
}
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
ui->btnStartThread->setEnabled(true);
ui->btnStart->setEnabled(false);
ui->btnStop->setEnabled(false);
ui->btnStopThread->setEnabled(false);
connect(&threadA, SIGNAL(started()),
this, SLOT(on_threadAStarted()));
connect(&threadA, SIGNAL(finished()),
this, SLOT(on_threadAFinished()));
connect(&threadA, SIGNAL(newValued(int,int)),
this, SLOT(on_threadAnewValue(int,int)));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::closeEvent(QCloseEvent *event)
{
if(threadA.isRunning())
{
threadA.stopThread();
threadA.wait();
}
event->accept();
}
void Dialog::on_btnStartThread_clicked()
{
threadA.start();
}
void Dialog::on_btnStart_clicked()
{
threadA.diceBegin();
}
void Dialog::on_btnStop_clicked()
{
threadA.dicePause();
}
void Dialog::on_btnStopThread_clicked()
{
threadA.stopThread();
}
void Dialog::on_btnClearText_clicked()
{
ui->plainTextEdit->clear();
}
void Dialog::on_threadAnewValue(int seq, int diceValue)
{
ui->plainTextEdit->appendPlainText(QString::asprintf("第%d次投色子: 点数%d", seq, diceValue));
}
void Dialog::on_threadAStarted()
{
ui->labelStatus->setText("Thread状态:started");
ui->btnStartThread->setEnabled(false);
ui->btnStart->setEnabled(true);
ui->btnStop->setEnabled(true);
ui->btnStopThread->setEnabled(true);
}
void Dialog::on_threadAFinished()
{
ui->labelStatus->setText("Thread状态:finished");
ui->btnStartThread->setEnabled(true);
ui->btnStart->setEnabled(false);
ui->btnStop->setEnabled(false);
ui->btnStopThread->setEnabled(false);
}
QMutex和QMutexLocker是基于互斥量的线程同步类
void DiceThread::readValue(int *seq, int *diceValue)
{
*seq = m_seq;
*diceValue = m_diceValue;
}
void DiceThread::run()
{
m_stop = false;
m_seq = 0;
qsrand(QTime::currentTime().second());
while (!m_stop) {
if(!m_Paused)
{
m_diceValue = 50;
msleep(50);
m_diceValue = qrand();
msleep(50);
m_diceValue = m_diceValue%6+1;
msleep(50);
m_seq++;
// emit newValued(m_seq, m_diceValue);
}
sleep(1);
}
quit();
}
void Dialog::on_TimerOut()
{
int seq, diceValue;
threadA.readValue(&seq, &diceValue);
ui->plainTextEdit->appendPlainText(QString::asprintf("第%d次投色子: 点数%d", seq, diceValue));
}
void DiceThread::readValue(int *seq, int *diceValue)
{
mMutex.lock();
*seq = m_seq;
*diceValue = m_diceValue;
mMutex.unlock();
}
void DiceThread::run()
{
m_stop = false;
m_seq = 0;
qsrand(QTime::currentTime().second());
while (!m_stop)
{
if(!m_Paused)
{
mMutex.lock();
m_diceValue = 50;
msleep(50);
m_diceValue = qrand();
msleep(50);
m_diceValue = m_diceValue % 6 + 1;
msleep(50);
m_seq++;
// emit newValued(m_seq, m_diceValue);
mMutex.unlock();
}
sleep(1);
}
quit();
}
void DiceThread::readValue(int *seq, int *diceValue)
{
QMutexLocker locker(&mMutex);
*seq = m_seq;
*diceValue = m_diceValue;
}
bool DiceThread::readValue(int *seq, int *diceValue)
{
// QMutexLocker locker(&mMutex);
if(mMutex.tryLock())
{
*seq = m_seq;
*diceValue = m_diceValue;
mMutex.unlock();
return true;
}
return false;
}
QReadWriteLock提供了以下主要函数:
QWaitCondition用于通知其他线程,如接收数据和处理数据之间通知。提供了一些函数:
#include "dicethread.h"
#include <QTime>
#include <QWaitCondition>
#include <QMutex>
int m_seq = 0;
int m_diceValue;
bool m_stop = false;
QMutex m_Mutex;
QWaitCondition waitCondition;
ProducerThread::ProducerThread()
{
}
void ProducerThread::stopThread()
{
m_stop = true;
}
void ProducerThread::run()
{
m_stop = false;
m_seq = 0;
qsrand(QTime::currentTime().second());
while (!m_stop)
{
m_Mutex.lock();
m_diceValue = qrand() % 6 + 1;
m_seq++;
m_Mutex.unlock();
waitCondition.wakeOne();
sleep(1);
}
quit();
}
ConsumerThread::ConsumerThread()
{
}
void ConsumerThread::stopThread()
{
m_stop = true;
waitCondition.wakeOne(); // 需要给wait置信号,否则阻塞无法结束
}
void ConsumerThread::run()
{
m_stop = false;
while (!m_stop)
{
m_Mutex.lock();
waitCondition.wait(&m_Mutex);
emit newValued(m_seq, m_diceValue);
m_Mutex.unlock();
msleep(100);
}
quit();
}
QSemaphore信号量通常用于保护一定数量的相同的资源。QSemaphore是实现信号量功能的类,提供了以下函数:
#include "threadtest.h"
#include <QSemaphore>
const int bufferSize = 8;
int buffer1[bufferSize] = {0};
int buffer2[bufferSize] = {0};
int curBuf = 1; // 当前采集数据使用的缓冲区
QSemaphore semEmptyBufs(2); // 两个资源
QSemaphore semFullBufs;
ThreadDAQ::ThreadDAQ()
{
}
void ThreadDAQ::stopThread()
{
m_stop = true;
}
void ThreadDAQ::run()
{
m_stop = false;
int counter = 0;
while(!m_stop)
{
semEmptyBufs.acquire();
for (int i = 0; i < bufferSize; ++i)
{
if(curBuf == 1)
{
buffer1[i] = counter;
}
else
{
buffer2[i] = counter;
}
counter++;
msleep(50);
}
if(curBuf == 1)
{
curBuf = 2;
}
else
{
curBuf = 1;
}
semFullBufs.release();
}
exit();
}
ThreadShow::ThreadShow()
{
}
void ThreadShow::stopThread()
{
m_stop = true;
}
void ThreadShow::run()
{
m_stop = false;
int seq = 0;
while(!m_stop)
{
semFullBufs.acquire();
int buf[bufferSize] = {0};
if(curBuf == 1)
{
memcpy(buf, buffer2, sizeof(int)*bufferSize);
}
else
{
memcpy(buf, buffer1, sizeof(int)*bufferSize);
}
emit newValue(buf, bufferSize, seq++);
semEmptyBufs.release();
}
exit();
}
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
ui->btnStopThread->setEnabled(false);
connect(&threadConsumer, SIGNAL(newValue(int*, int, int)),
this, SLOT(on_threadNewValue(int*, int, int)));
connect(&threadProducer, SIGNAL(started()),
this, SLOT(on_threadProducer_started()));
connect(&threadProducer, SIGNAL(finished()),
this, SLOT(on_threadProducer_finished()));
connect(&threadConsumer, SIGNAL(started()),
this, SLOT(on_threadConsumer_started()));
connect(&threadConsumer, SIGNAL(finished()),
this, SLOT(on_threadConsumer_finished()));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::on_threadNewValue(int *data, int count, int seq)
{
QString str = QString::asprintf("第%03d次,内容:", seq);
for (int var = 0; var < count; ++var)
{
str += QString::asprintf("%03d ,", data[var]);
}
ui->plainTextEdit->appendPlainText(str);
}
void Dialog::on_btnStartThread_clicked()
{
threadConsumer.start();
threadProducer.start();
ui->btnStartThread->setEnabled(false);
ui->btnStopThread->setEnabled(true);
}
void Dialog::on_btnStopThread_clicked()
{
threadProducer.stopThread();
threadConsumer.stopThread();
ui->btnStartThread->setEnabled(true);
ui->btnStopThread->setEnabled(false);
}
void Dialog::on_btnClearText_clicked()
{
ui->plainTextEdit->clear();
}
void Dialog::on_threadProducer_started()
{
ui->labelProducer->setText("Producer线程:started");
}
void Dialog::on_threadProducer_finished()
{
ui->labelProducer->setText("Producer线程:finished");
}
void Dialog::on_threadConsumer_started()
{
ui->labelConsumer->setText("Consumer线程:started");
}
void Dialog::on_threadConsumer_finished()
{
ui->labelConsumer->setText("Consumer线程:finished");
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。