基于QWaitCondition的线程同步

	QWaitCondition提供了另一种改进的线程同步方法,与QMutex结合,可以使一个线程在满足一定条件下时通知其他多
个线程,使它们及时做出相应,相对于互斥量效率高一点。
	QWaitCondition提供如下函数:
	wait(QMutex* lockedmutex):解锁互斥量lockedmutex,并阻塞等待唤醒,被唤醒后锁定lockedmutex并退出函数
	wakeAll():唤醒所有处于等待状态的线程,唤醒顺序不确定,由操作系统调度策略决定
	wakeOne():	唤醒一个处于等待状态的线程,不确定唤醒哪一个,由操作系统调度策略决定

以下是根据QWaitCondition “生产者-消费者”模式改进的投掷骰子的程序:

QMutex mutex;
QWaitCondition diceValueAvailabel;
int seq = 0;
int diceValue = 0;
QThreadProducer::QThreadProducer(QObject* parent)
	: QThread(parent)
{
	m_gonOn = false;
}
QThreadProducer::~QThreadProducer() {
}
void QThreadProducer::stopThread() {
	m_gonOn = false;
}
void QThreadProducer::run() {
	m_gonOn = true;
	seq = 0;
	qsrand(QTime::currentTime().msec());
	while (m_gonOn) {
		mutex.lock();
		diceValue = (qrand() % 6) + 1;
		seq++;
		qDebug() << "QThreadProducer seq: " << seq << " diceValue: " << diceValue;
		mutex.unlock();
		diceValueAvailabel.wakeAll();
		msleep(500);
	}
}
QThreadConsumer::QThreadConsumer(QObject* parent)
	: QThread(parent)
{
	m_gonOn = false;
}
QThreadConsumer::~QThreadConsumer() {
}
void QThreadConsumer::stopThread() {
	m_gonOn = false;
}
void QThreadConsumer::run() {
	m_gonOn = true;
	while (m_gonOn) {
		mutex.lock();
		diceValueAvailabel.wait(&mutex);
		qDebug() << "returnDiceValueSignal seq: " << seq << " diceValue: " << diceValue;
		emit returnDiceValueSignal(seq, diceValue);
		mutex.unlock();
	}
}

主线程调用代码为:

void QthreadProject::on_startThreadBtn_clicked() {
    if (!m_consumer->isRunning())
        m_consumer->start();
    if (!m_producer->isRunning())
        m_producer->start();
    ui.startThreadBtn->setEnabled(false);
    ui.stopThreadBtn->setEnabled(true);
}
void QthreadProject::on_stopThreadBtn_clicked() {
    if (m_producer->isRunning()) {
        m_producer->stopThread();
        m_producer->quit();
        m_producer->wait();
    }
    if (m_consumer->isRunning()) {
        m_consumer->stopThread();
        m_consumer->terminate();//必须用terminate()终结线程,因为consumer线程可能还处于条件等待的
     阻塞状态中,无法正常结束
        m_consumer->wait();
    }
    ui.startThreadBtn->setEnabled(true);
    ui.stopThreadBtn->setEnabled(false);
   }
void QthreadProject::on_clearBtn_clicked() {
    ui.plainTextEdit->clear();
}
void QthreadProject::returnDiceValueSlot(int seq, int dicevalue) {
    QString str = QString::asprintf("第%d次投掷骰子,点数为%d", seq, dicevalue);
    ui.plainTextEdit->appendPlainText(str);
    QPixmap pix;
    QString filename = QString::asprintf("icon/%d.png", dicevalue);
    pix.load(filename);
    ui.label->setPixmap(pix);
    ui.label->setScaledContents(true);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值