西安注册公司在哪个网站系统,怎么创办个人网站,wordpress虚拟商城,小程序开发者工具下载一、多线程程序
QThread类提供了管理线程的方法#xff1a;一个对象管理一个线程一般从QThread继承一个自定义类#xff0c;重载run函数
1、实现程序 #xff08;1#xff09;创建项目#xff0c;基于QDialog
#xff08;2#xff09;添加类#xff0c;修改基于QThr…一、多线程程序
QThread类提供了管理线程的方法一个对象管理一个线程一般从QThread继承一个自定义类重载run函数
1、实现程序 1创建项目基于QDialog
2添加类修改基于QThread #ifndef DICETHREAD_H
#define DICETHREAD_H#include QThreadclass DiceThread : public QThread
{Q_OBJECTprivate: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 QTimeDiceThread::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()%61;m_seq;emit newValued(m_seq, m_diceValue);}sleep(1);}quit();
}
3实现按钮功能
#include dialog.h
#include ui_dialog.hDialog::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是基于互斥量的线程同步类QMutex定义的实力是互斥量主要提供了三个函数 lock()锁定互斥量如果另一个线程锁定了这个互斥量将阻塞直到另一个解锁unlock()解锁一个互斥量trylock()尝试锁定一个互斥量如果成功返回true失败其他线程已经锁定这个互斥量返回false不阻塞线程。 QMutexLocker简化了互斥量的处理 构造一个函数接受一个互斥量作为参数并将其锁定析构函数解锁该互斥量
1、实现程序
1拷贝上一个项目
2修改程序为直接读取
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%61;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));
}3使用QMutex互斥量
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();
}4使用QMutexLocker
void DiceThread::readValue(int *seq, int *diceValue)
{QMutexLocker locker(mMutex);*seq m_seq;*diceValue m_diceValue;
}5使用QMutex.trylock
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提供了以下主要函数lockForRead()只读方式锁定资源如果有其他线程以写入方式锁定这个函数会阻塞lockForWrite()以写入方式锁定资源如果本线程或者其他线程以读取或写入锁定资源则函数阻塞unlock()解锁tryLockForRead()是lockForRead非阻塞版本tryLockForWrite()是lockForWrite非阻塞版本读写锁同样有QReadLocker和QWriteLocker
四、条件变量QWaitCondition
QWaitCondition用于通知其他线程如接收数据和处理数据之间通知。提供了一些函数wait(QMutex *lockedMutex)进入等待状态解锁互斥量lockMutex被唤醒后锁定lockMutex并退出函数wakeAll()唤醒所有处于等待的线程线程唤醒的顺序不确定有操作系统调度策略决定QakeOne()唤醒一个处于等待状态的线程唤醒哪个线程不确定由操作系统调度策略决定
1、实现程序 1拷贝上一个项目
2使用QWaitCondition设置数据更新
#include dicethread.h
#include QTime
#include QWaitCondition
#include QMutexint 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是实现信号量功能的类提供了以下函数acquire(int n)尝试获得n个资源如果不够将阻塞线程直到n个资源可用release(int n)释放资源如果资源已经全部可用则可扩充资源总数int available()返回房前信号量的资源个数bool tryAcquire(int n1)尝试获取n个资源不成功是不阻塞线程
1、实现程序 1创建项目基于QDIalog 2创建线程类
3使用信号量实现功能
#include threadtest.h
#include QSemaphoreconst 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.hDialog::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);
}