当前位置: 首页 > news >正文

黟县网站建设深圳画册设计公司排名

黟县网站建设,深圳画册设计公司排名,onedrive wordpress,北京市住房及城乡建设部网站在多线程的程序中#xff0c;多个线程之间的同步实际上就是它们之间的协调问题。例如上一小节讲到的3个线程的例子中#xff0c;假设 threadDAQ 写满一个缓冲区之后#xff0c;threadShow 和 threadSaveFile 才能对缓冲区进行读操作。前面采用的互斥量和基于 OReadWriteLock…在多线程的程序中多个线程之间的同步实际上就是它们之间的协调问题。例如上一小节讲到的3个线程的例子中假设 threadDAQ 写满一个缓冲区之后threadShow 和 threadSaveFile 才能对缓冲区进行读操作。前面采用的互斥量和基于 OReadWriteLock 的方法都是对资源的锁定和解锁避免同时访问资源时发生冲突。在一个线程解锁资源后不能及时通知其他线程。此处类似于C中的条件变量具体可参考C新特性36_条件变量的使用介绍C11中条件变量的用法条件变量必须搭配互斥体和条件使用条件、条件变量、互斥体三胞胎需要同时使用 QWaitCondition 提供了另外一种改进的线程同步方法QWaitCondition 与QMutex 结合可以使一个线程在满足一定条件时通知其他多个线程使它们及时作出响应这样比只使用互斥量效率要高一些。例如threadDAQ 在写满一个缓冲区之后及时通知 threadShow 和threadSaveFile,使它们可以及时读取缓冲区数据。 QWaitCondition 提供如下一些函数: wait(QMutex *lockedMutex)解锁互斥量 lockedMutex并阻塞等待唤醒条件被唤醒后锁定lockedMutex 并退出函数;wakeAll()唤醒所有处于等待状态的线程线程唤醒的顺序不确定由操作系统的调度策略决定:wakeOne()唤醒一个处于等待状态的线程唤醒哪个线程不确定由操作系统的调度策略决定。 QWaitCondition 一般用于“生产者/消费者”(producer/consumer)模型中。“生产者”产生数据“消费者”使用数据前述的数据采集、显示与存储的三线程例子就适用这种模型。 文章目录 1. 实例分析2. 源码2.1 dialog.h2.2 dialog.cpp2.3 qmythread.h2.4 qmythread.cpp 1. 实例分析 创建实例程序 samp13_4将掷骰子的程序修改为 producer/consumer 模型一个线程类QThreadProducer 专门负责掷骰子产生点数:一个线程类QThreadConsumer 专门及时读取数据并送给主线程进行显示。这两个类定义在一个文件 qmythread.h 里定义代码如下: #ifndef QMYTHREAD_H #define QMYTHREAD_H//#include QObject #include QThreadclass QThreadProducer : public QThread {Q_OBJECT private:bool m_stopfalse; //停止线程 protected:void run() Q_DECL_OVERRIDE; public:QThreadProducer();void stopThread(); };class QThreadConsumer : public QThread {Q_OBJECT private:bool m_stopfalse; //停止线程 protected:void run() Q_DECL_OVERRIDE; public:QThreadConsumer();void stopThread(); signals:void newValue(int seq,int diceValue); }; #endif // QMYTHREAD_H QThreadProducer用于掷骰子但是去掉了开始和暂停的功能线程一启动就连续地掷骰子。QThreadConsumer用于读取掷骰子的次数和点数并用发射信号方式把数据传递出去。这两个类的实现代码在一个文件qmythread.cpp里下面是这两个类的实现代码的主要部分 QMutex mutex; QWaitCondition newdataAvailable;int seq0;//序号 int diceValue;void QThreadProducer::run() {m_stopfalse;//启动线程时令m_stopfalseseq0;qsrand(QTime::currentTime().msec());//随机数初始化qsrand是线程安全的while(!m_stop)//循环主体{mutex.lock();diceValueqrand(); //获取随机数diceValue(diceValue % 6)1;seq;mutex.unlock();newdataAvailable.wakeAll();//唤醒所有线程有新数据了msleep(500); //线程休眠100ms} }void QThreadConsumer::run() {m_stopfalse;//启动线程时令m_stopfalsewhile(!m_stop)//循环主体{mutex.lock();newdataAvailable.wait(mutex);//会先解锁mutex使其他线程可以使用mutexemit newValue(seq,diceValue);mutex.unlock(); // msleep(100); //线程休眠100ms}}掷骰子的次数和点数的变量定义为共享变量这样两个线程都可以访问。定义了互斥量mutex定义了QWaitCondition实例newdataAvailable表示有新数据可用了。 QThreadProducer.:run()函数负责每隔 500 毫秒掷骰子产生一次数据新数据产生后通过等待条件唤醒所有等待的线程即: newdataAvailable.wakeAll();//唤醒所有线程有新数据了 QThreadConsumer::run()函数中的while循环首先需要将互斥量锁定再执行下面的一条语句 newdataAvailable.wait(mutex);//会先解锁mutex使其他线程可以使用mutex 这条语句以 mutex 作为输入参数内部会首先解锁 mutex使其他线程可以使用 mutexnewdataAvailable 进入等待状态。当 QThreadProducer 产生新数据使用 newdataAvailable.wakeAll()唤醒所有线程后newdataAvailablewait(mutex)会再次锁定 mutex然后退出阻塞状态以执行后面的语句。 所以使用 QWaitCondition 可以使 QThreadConsumer 线程的执行过程进入等待状态。在QThreadProducer 线程满足条件后唤醒QThreadConsumer 线程及时退出等待状态继续执行后面的程序。 使用QThreadProducer和QThreadConsumer 实现掷骰子的实例程序samp13_4运行时界面如图13-2 所示与实例 samp13_1 的运行界面类似只是取消了开始和暂停掷假子的按钮下方的状态标签显示了两个线程的状态。 窗口的 Dialog 类的定义如下(省略了按钮槽函数等一些不重要的部分): #ifndef DIALOG_H #define DIALOG_H#include QDialog #include QTimer#include qmythread.hnamespace Ui { class Dialog; }class Dialog : public QDialog {Q_OBJECTprivate:QThreadProducer threadProducer;QThreadConsumer threadConsumer; protected:void closeEvent(QCloseEvent *event); public:explicit Dialog(QWidget *parent 0);~Dialog();private slots:void onthreadA_started();void onthreadA_finished();void onthreadB_started();void onthreadB_finished();void onthreadB_newValue(int seq, int diceValue);...private:Ui::Dialog *ui; };#endif // DIALOG_H 这里主要是定义了两个线程的实例并定义了几个自定义槽函数。采用信号与槽的方式与threadConsumer建立通信并获取数据。Dialog 的构造函数主要完成信号与槽函数的关联5 个自定义槽函数的代码与实例 samp13_1 的相同或相似这几个函数的代码不再详细列出。 启动线程按钮的代码如下 void Dialog::on_btnStartThread_clicked() {//启动线程threadConsumer.start();threadProducer.start();ui-btnStartThread-setEnabled(false);ui-btnStopThread-setEnabled(true); }两个线程启动的先后顺序不应调换应先启动 threadConsumer使其先进入 wait 状态后启动 threadProducer这样在threadProducer 里 wakeAll()时 threadConsumer 就可以及时响应否则会丢失一次掷骰子的数据。 “结束线程”按钮的代码如下 void Dialog::on_btnStopThread_clicked() {//结束线程threadProducer.stopThread();//结束线程的run()函数执行threadProducer.wait();//// threadConsumer.stopThread();//结束线程的run()函数执行threadConsumer.terminate(); //因为threadB可能处于等待状态所以用terminate强制结束threadConsumer.wait();//ui-btnStartThread-setEnabled(true);ui-btnStopThread-setEnabled(false); }结束线程时若按照上面的顺序先结束 threadProducer 线程则必须使用terminate()来强制结束threadConsumer 线程因为 threadConsumer 可能还处于条件等待的阻塞状态中将无法正常结束线程。 2. 源码 2.1 dialog.h #ifndef DIALOG_H #define DIALOG_H#include QDialog #include QTimer#include qmythread.hnamespace Ui { class Dialog; }class Dialog : public QDialog {Q_OBJECTprivate:QThreadProducer threadProducer;QThreadConsumer threadConsumer; protected:void closeEvent(QCloseEvent *event); public:explicit Dialog(QWidget *parent 0);~Dialog();private slots:void onthreadA_started();void onthreadA_finished();void onthreadB_started();void onthreadB_finished();void onthreadB_newValue(int seq, int diceValue);void on_btnClear_clicked();void on_btnStopThread_clicked();void on_btnStartThread_clicked();private:Ui::Dialog *ui; };#endif // DIALOG_H 2.2 dialog.cpp #include dialog.h #include ui_dialog.hvoid Dialog::closeEvent(QCloseEvent *event) {//关闭窗口if (threadProducer.isRunning()){threadProducer.stopThread();threadProducer.wait();}if (threadConsumer.isRunning()){threadConsumer.terminate(); //因为threadB可能处于等待状态所以用terminate强制结束threadConsumer.wait();//}event-accept(); }Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) {ui-setupUi(this);connect(threadProducer,SIGNAL(started()),this,SLOT(onthreadA_started()));connect(threadProducer,SIGNAL(finished()),this,SLOT(onthreadA_finished()));connect(threadConsumer,SIGNAL(started()),this,SLOT(onthreadB_started()));connect(threadConsumer,SIGNAL(finished()),this,SLOT(onthreadB_finished()));connect(threadConsumer,SIGNAL(newValue(int,int)),this,SLOT(onthreadB_newValue(int,int))); }Dialog::~Dialog() {delete ui; }void Dialog::onthreadA_started() {ui-LabA-setText(Thread Producer状态: started); }void Dialog::onthreadA_finished() {ui-LabA-setText(Thread Producer状态: finished); }void Dialog::onthreadB_started() {ui-LabB-setText(Thread Consumer状态: started); }void Dialog::onthreadB_finished() {ui-LabB-setText(Thread Consumer状态: finished); }void Dialog::onthreadB_newValue(int seq,int diceValue) {QString strQString::asprintf(第 %d 次掷骰子点数为%d,seq,diceValue);ui-plainTextEdit-appendPlainText(str);QPixmap pic;QString filenameQString::asprintf(:/dice/images/d%d.jpg,diceValue);pic.load(filename);ui-LabPic-setPixmap(pic); }void Dialog::on_btnClear_clicked() {ui-plainTextEdit-clear(); }void Dialog::on_btnStopThread_clicked() {//结束线程threadProducer.stopThread();//结束线程的run()函数执行threadProducer.wait();//// threadConsumer.stopThread();//结束线程的run()函数执行threadConsumer.terminate(); //因为threadB可能处于等待状态所以用terminate强制结束threadConsumer.wait();//ui-btnStartThread-setEnabled(true);ui-btnStopThread-setEnabled(false); }void Dialog::on_btnStartThread_clicked() {//启动线程threadConsumer.start();threadProducer.start();ui-btnStartThread-setEnabled(false);ui-btnStopThread-setEnabled(true); } 2.3 qmythread.h #ifndef QMYTHREAD_H #define QMYTHREAD_H//#include QObject #include QThreadclass QThreadProducer : public QThread {Q_OBJECT private:bool m_stopfalse; //停止线程 protected:void run() Q_DECL_OVERRIDE; public:QThreadProducer();void stopThread(); };class QThreadConsumer : public QThread {Q_OBJECT private:bool m_stopfalse; //停止线程 protected:void run() Q_DECL_OVERRIDE; public:QThreadConsumer();void stopThread(); signals:void newValue(int seq,int diceValue); }; #endif // QMYTHREAD_H 2.4 qmythread.cpp #include qmythread.h #include QWaitCondition #include QTime #include QMutexQMutex mutex; QWaitCondition newdataAvailable;int seq0;//序号 int diceValue;QThreadProducer::QThreadProducer() {}void QThreadProducer::stopThread() {QMutexLocker locker(mutex);m_stoptrue; }void QThreadProducer::run() {m_stopfalse;//启动线程时令m_stopfalseseq0;qsrand(QTime::currentTime().msec());//随机数初始化qsrand是线程安全的while(!m_stop)//循环主体{mutex.lock();diceValueqrand(); //获取随机数diceValue(diceValue % 6)1;seq;mutex.unlock();newdataAvailable.wakeAll();//唤醒所有线程有新数据了msleep(500); //线程休眠100ms} }void QThreadConsumer::run() {m_stopfalse;//启动线程时令m_stopfalsewhile(!m_stop)//循环主体{mutex.lock();newdataAvailable.wait(mutex);//会先解锁mutex使其他线程可以使用mutexemit newValue(seq,diceValue);mutex.unlock(); // msleep(100); //线程休眠100ms}}QThreadConsumer::QThreadConsumer() {}void QThreadConsumer::stopThread() {QMutexLocker locker(mutex);m_stoptrue; }
http://www.dnsts.com.cn/news/162183.html

相关文章:

  • 如何网上建设网站北京的网站建设公司
  • 网站前后端用什么软件做域名买好怎么开始做网站
  • 郑州做网站公司有哪些外海网站如何做网站的推广
  • 做定制校服的网站绍兴柯桥哪里有做网站的
  • 家居网站建设 百度文库深圳工业设计大展2021
  • 金华网站制作费用设计师学习网站
  • 郑州市金水区建设局官方网站阳泉建设公司网站
  • 网站建设所需技术县级林业网站建设管理
  • 学习网站建设要什么学历各大网站响应生态建设
  • 网站建设如何不被忽悠网站前端设计理念
  • 网站建设地带网站设计自已申请
  • 公司网站做门户备案刚开始做写手上什么网站
  • 网站排名优化方案wordpress在线文档下载
  • 官网站内优化怎么做 2018网络平台有哪些类型
  • 枣庄市建设局网站迅速百度网站自然排名
  • dw中怎样做网站二级页面宁波市建设工程检测协会网站
  • 都兰县公司网站建设徐州市城乡和城乡建设厅网站首页
  • 做电影网站需要哪些条件各地平台网站
  • 网站建站禄劝彝族苗族网站建设
  • 山东省聊城建设学校网站360开户
  • 专业的网站设计师自己建网站难吗
  • .net做网站用mvc重庆软件开发公司
  • 网站建设合同制定制型网站制作哪家好
  • 网站登录慢制作书签 小学生一年级
  • 昆明网站制作宁波公司查询
  • 网站建设企业邮箱制作网站建立健全()和安全生产规章制度
  • 响应式网站制作工具免费建站宝盒
  • h5响应式网站模板制作做招聘网站价格
  • qq安全中心信任网站网络营销策划书的结构
  • 互助盘网站开发沈阳专业网站制作设计