例子
创建两个线程,让两个线程先后运行,一秒只能有一个线程在运行,一个线程在运行时另一个线程处于阻塞状态,两个线程交替运行。
思路
利用信号量来做,两个线程两个信号量,开始时两个信号量都是0,当信号量为0时,继续获取也就是-1操作时,就会阻塞,所以假设有AB两个线程,每秒都让信号量-1,刚开始先让A 的信号量+1,那么第一秒只有A会运行,运行之后给B的信号量+1,第二秒A为0会阻塞,B为1会执行,一秒后A的信号量+1…依次循环,实现对AB线程的循环调用。
代码
用到的信号量 QSemaphore
这里对信号进行封装,使得一个变量可以控制两个信号量,并且使用单例模式,避免传递参数。
mythread.h (自定义线程函数 继承自QThread)
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
#include <QThread>
#include "semaphone.h"
class mythread : public QThread
{
Q_OBJECT
public:
mythread(QString name,QObject * parent = 0);
private:
QString name;
protected:
//重写线程run函数
virtual void run();
signals:
void sendmsg(QString);
};
#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
mythread::mythread(QString name, QObject *parent):
name(name),
QThread(parent)
{
semaphone *sem = semaphone::getInstance();
if(name =="A"){
sem->s1release();//先把线程1的信号量变成1
}
}
void mythread::run()
{
//单例获取信号量
semaphone *sem = semaphone::getInstance();
while(1){
//如果调用该线程的是A 那么请求A 否则请求B
if(name == "A"){
sem->s1acquire();
}else{
sem->s2acquire();
}
//发送信号
emit sendmsg(name);
//睡眠1s
this->sleep(1);
//如果调用的是线程A 那么给线程B的信号量+1 下次就会调用线程B
if(name == "A"){
sem->s2release();
}else{
sem->s1release();
}
}
}
semaphone.h (自定义信号函数 )
#ifndef SEMAPHONE_H
#define SEMAPHONE_H
#include <QWidget>
#include <QObject>
#include <QSemaphore>
class semaphone
{
private:
semaphone();
static semaphone *instance;
QSemaphore s1;//信号量s1用来控制线程A
QSemaphore s2;//信号量s2用来控制线程B
public:
static semaphone *getInstance(); //单例模式
void s1acquire();//请求S1 -1
void s1release();//释放S1 +1
void s2acquire();//请求S2 -1
void s2release();//释放S2 +1
};
#endif // SEMAPHONE_H
semaphone.cpp
#include "semaphone.h"
semaphone::semaphone()
{
}
semaphone *semaphone::getInstance()
{
if(instance == NULL){
instance = new semaphone;
}
return instance;
}
void semaphone::s1acquire(){
s1.acquire();
}
void semaphone::s1release(){
s1.release();
}
void semaphone::s2acquire(){
s2.acquire();
}
void semaphone::s2release(){
s2.release();
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "mythread.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
//两个线程指针
mythread *t1;
mythread *t2;
public slots:
void rcvmsg(QString name);
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//线程初始化
t1 = new mythread("A",this);
t2 = new mythread("B",this);
//线程开始
t1->start();
t2->start();
//连接信号槽
QObject::connect(t1,SIGNAL(sendmsg(QString)),this,SLOT(rcvmsg(QString)));
QObject::connect(t2,SIGNAL(sendmsg(QString)),this,SLOT(rcvmsg(QString)));
}
Widget::~Widget()
{
delete ui;
}
void Widget::rcvmsg(QString name)
{
//在文本框中显示调用线程的名字
ui->textEdit->append(name);
}
main.cpp
#include "widget.h"
#include <QApplication>
#include "semaphone.h"
//声明信号的单例
semaphone* semaphone::instance = NULL;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
效果
版权声明:本文为weixin_43701705原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。