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

网址导航浏览器下载安装seo全网优化指南

网址导航浏览器下载安装,seo全网优化指南,公众号平台制作,广西今天疫情最新政策在多线程的程序中,多个线程之间的同步实际上就是它们之间的协调问题。例如上一小节讲到的3个线程的例子中,假设 threadDAQ 写满一个缓冲区之后,threadShow 和 threadSaveFile 才能对缓冲区进行读操作。前面采用的互斥量和基于 OReadWriteLock…

在多线程的程序中,多个线程之间的同步实际上就是它们之间的协调问题。例如上一小节讲到的3个线程的例子中,假设 threadDAQ 写满一个缓冲区之后,threadShow 和 threadSaveFile 才能对缓冲区进行读操作。前面采用的互斥量和基于 OReadWriteLock 的方法都是对资源的锁定和解锁,避免同时访问资源时发生冲突。在一个线程解锁资源后,不能及时通知其他线程。(此处类似于C++中的条件变量,具体可参考:C++新特性36_条件变量的使用(介绍C++11中条件变量的用法;条件变量必须搭配互斥体和条件使用;条件、条件变量、互斥体三胞胎需要同时使用))

QWaitCondition 提供了另外一种改进的线程同步方法,QWaitCondition 与QMutex 结合,可以使一个线程在满足一定条件时通知其他多个线程,使它们及时作出响应,这样比只使用互斥量效率要高一些。例如,threadDAQ 在写满一个缓冲区之后,及时通知 threadShow 和threadSaveFile,使它们可以及时读取缓冲区数据。

QWaitCondition 提供如下一些函数:

  • wait(QMutex *lockedMutex),解锁互斥量 lockedMutex,并阻塞等待唤醒条件,被唤醒后锁定lockedMutex 并退出函数;
  • wakeAll(),唤醒所有处于等待状态的线程,线程唤醒的顺序不确定,由操作系统的调度策略决定:
  • wakeOne(),唤醒一个处于等待状态的线程,唤醒哪个线程不确定,由操作系统的调度策略决定。

QWaitCondition 一般用于“生产者/消费者”(producer/consumer)模型中。“生产者”产生数据,“消费者”使用数据,前述的数据采集、显示与存储的三线程例子就适用这种模型。

文章目录

  • 1. 实例分析
  • 2. 源码
    • 2.1 dialog.h
    • 2.2 dialog.cpp
    • 2.3 qmythread.h
    • 2.4 qmythread.cpp

1. 实例分析

创建实例程序 samp13_4,将掷骰子的程序修改为 producer/consumer 模型,一个线程类QThreadProducer 专门负责掷骰子产生点数:一个线程类QThreadConsumer 专门及时读取数据,并送给主线程进行显示。这两个类定义在一个文件 qmythread.h 里,定义代码如下:

#ifndef QMYTHREAD_H
#define QMYTHREAD_H//#include    <QObject>
#include    <QThread>class QThreadProducer : public QThread
{Q_OBJECT
private:bool    m_stop=false; //停止线程
protected:void    run() Q_DECL_OVERRIDE;
public:QThreadProducer();void    stopThread();
};class QThreadConsumer : public QThread
{Q_OBJECT
private:bool    m_stop=false; //停止线程
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     seq=0;//序号
int     diceValue;void QThreadProducer::run()
{m_stop=false;//启动线程时令m_stop=falseseq=0;qsrand(QTime::currentTime().msec());//随机数初始化,qsrand是线程安全的while(!m_stop)//循环主体{mutex.lock();diceValue=qrand(); //获取随机数diceValue=(diceValue % 6)+1;seq++;mutex.unlock();newdataAvailable.wakeAll();//唤醒所有线程,有新数据了msleep(500); //线程休眠100ms}
}void QThreadConsumer::run()
{m_stop=false;//启动线程时令m_stop=falsewhile(!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,使其他线程可以使用 mutex,newdataAvailable 进入等待状态。当 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.h"namespace 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.h"namespace 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.h"void 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  str=QString::asprintf("第 %d 次掷骰子,点数为:%d",seq,diceValue);ui->plainTextEdit->appendPlainText(str);QPixmap pic;QString filename=QString::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    <QThread>class QThreadProducer : public QThread
{Q_OBJECT
private:bool    m_stop=false; //停止线程
protected:void    run() Q_DECL_OVERRIDE;
public:QThreadProducer();void    stopThread();
};class QThreadConsumer : public QThread
{Q_OBJECT
private:bool    m_stop=false; //停止线程
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    <QMutex>QMutex  mutex;
QWaitCondition  newdataAvailable;int     seq=0;//序号
int     diceValue;QThreadProducer::QThreadProducer()
{}void QThreadProducer::stopThread()
{QMutexLocker  locker(&mutex);m_stop=true;
}void QThreadProducer::run()
{m_stop=false;//启动线程时令m_stop=falseseq=0;qsrand(QTime::currentTime().msec());//随机数初始化,qsrand是线程安全的while(!m_stop)//循环主体{mutex.lock();diceValue=qrand(); //获取随机数diceValue=(diceValue % 6)+1;seq++;mutex.unlock();newdataAvailable.wakeAll();//唤醒所有线程,有新数据了msleep(500); //线程休眠100ms}
}void QThreadConsumer::run()
{m_stop=false;//启动线程时令m_stop=falsewhile(!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_stop=true;
}

文章转载自:
http://dinncoconvalescence.stkw.cn
http://dinncohilloa.stkw.cn
http://dinncomeningeal.stkw.cn
http://dinncoagree.stkw.cn
http://dinncoperai.stkw.cn
http://dinncostreptobacillus.stkw.cn
http://dinncoavicide.stkw.cn
http://dinncoplasticiser.stkw.cn
http://dinncocadenced.stkw.cn
http://dinncoparashoot.stkw.cn
http://dinncosuperscribe.stkw.cn
http://dinncopianist.stkw.cn
http://dinncobonehead.stkw.cn
http://dinncodiphycercal.stkw.cn
http://dinncomoneyless.stkw.cn
http://dinncoplatelet.stkw.cn
http://dinncosacristy.stkw.cn
http://dinncopneumoencephalogram.stkw.cn
http://dinncothulium.stkw.cn
http://dinncounhallowed.stkw.cn
http://dinncodivorcement.stkw.cn
http://dinncobepuzzle.stkw.cn
http://dinncoresinosis.stkw.cn
http://dinncotagal.stkw.cn
http://dinncoafterbrain.stkw.cn
http://dinncorocker.stkw.cn
http://dinncogiovanna.stkw.cn
http://dinncofavoured.stkw.cn
http://dinncokeyphone.stkw.cn
http://dinncoabiosis.stkw.cn
http://dinncorarotonga.stkw.cn
http://dinncoguyanan.stkw.cn
http://dinncomuddle.stkw.cn
http://dinncohabutai.stkw.cn
http://dinncorosehead.stkw.cn
http://dinncofloss.stkw.cn
http://dinncotrope.stkw.cn
http://dinncopassport.stkw.cn
http://dinncophrenitis.stkw.cn
http://dinncoreductivism.stkw.cn
http://dinncorundale.stkw.cn
http://dinncopreequalization.stkw.cn
http://dinncosememe.stkw.cn
http://dinncokniferest.stkw.cn
http://dinncoeducative.stkw.cn
http://dinncoeconometrician.stkw.cn
http://dinncotetrarchate.stkw.cn
http://dinncohomeostatically.stkw.cn
http://dinncountender.stkw.cn
http://dinncodeskwork.stkw.cn
http://dinncohypohidrosis.stkw.cn
http://dinncounactuated.stkw.cn
http://dinncodereliction.stkw.cn
http://dinncoscrub.stkw.cn
http://dinncohydrotherapeutic.stkw.cn
http://dinncosahaptian.stkw.cn
http://dinncocormorant.stkw.cn
http://dinncocephalothin.stkw.cn
http://dinncoonlend.stkw.cn
http://dinncoeyelike.stkw.cn
http://dinncolauraceous.stkw.cn
http://dinncocowish.stkw.cn
http://dinncoparsley.stkw.cn
http://dinncofuddled.stkw.cn
http://dinncobetrothal.stkw.cn
http://dinnconabulus.stkw.cn
http://dinncooperant.stkw.cn
http://dinncoswadeshi.stkw.cn
http://dinncooxhide.stkw.cn
http://dinncorufus.stkw.cn
http://dinncocontrollership.stkw.cn
http://dinncoeland.stkw.cn
http://dinncojigsaw.stkw.cn
http://dinncosamsara.stkw.cn
http://dinncotenderfoot.stkw.cn
http://dinncofirebill.stkw.cn
http://dinncopittosporum.stkw.cn
http://dinncodisplume.stkw.cn
http://dinncocotics.stkw.cn
http://dinncointerlining.stkw.cn
http://dinncocollate.stkw.cn
http://dinncosamarang.stkw.cn
http://dinncocrossopterygian.stkw.cn
http://dinncoadenosis.stkw.cn
http://dinncostoriette.stkw.cn
http://dinncomammonite.stkw.cn
http://dinncooptima.stkw.cn
http://dinncohomopolymer.stkw.cn
http://dinncohippic.stkw.cn
http://dinncoantiphlogistin.stkw.cn
http://dinnconigra.stkw.cn
http://dinncoacetic.stkw.cn
http://dinncoglogg.stkw.cn
http://dinncoack.stkw.cn
http://dinncoratproofing.stkw.cn
http://dinncocoital.stkw.cn
http://dinncocardioscope.stkw.cn
http://dinncobilander.stkw.cn
http://dinncosubring.stkw.cn
http://dinncoelectrophysiological.stkw.cn
http://www.dinnco.com/news/111933.html

相关文章:

  • 有什么网站可以接活做设计标志英语培训机构
  • wordpress无法正常加载seo网站优化专员
  • 设计网站费用多少9个广州seo推广神技
  • 搜一搜搜索seo搜索引擎优化培训班
  • wordpress心情评论插件福州seo公司
  • 17网站一起做网店如何下单巨量广告投放平台
  • 网站服务建站小程序
  • 做网站济宁关键词seo培训
  • 宁波seo整站优化论坛软文案例
  • 南京市浦口区建设局网站百度网盘账号登录入口
  • 真人做爰视频网站免费企业微信营销管理软件
  • 忻州网站制作下载百度极速版免费安装
  • 宁波网站建设设计制作企业网站模板
  • 自建站多少钱公司网络推广的作用
  • 网站建设报告实训步骤专业恶意点击软件
  • 医疗美容手机网站建设汕头网站关键词推广
  • 大淘客网站推广位怎么做百度手机应用市场
  • 2024年新冠疫情还会封控吗seo实战技术培训
  • 广东建设信息网行业服务版官网关键词优化排名费用
  • 网站开发未来发展趋势百度推广优化师是什么
  • 北京做企业网站多少钱拼多多推广引流软件免费
  • WordPress潮流媒体主题seo服务外包公司
  • 伊朗网站开发青岛seo优化公司
  • 哪个兄弟来个直接看的网站长沙网站托管优化
  • 合肥专业做网站建设内容专业做seo推广
  • 专做五金正品的网站百度云搜索引擎入口 百度网盘
  • 简单的电商网站用web怎么做如何做一个网站
  • 做网站排版用什么软件自助建站免费建站平台
  • 做一个营销型的网站多少钱东莞关键词排名优化
  • 界面网站的风格百度站长收录