前言:
最近没更新博客啊,主要是我的二叉树算法还在调试,又面临毕业了,各种实验啊,找工作啊,又有了各种的论文啊,实在是没时间了,这几天突发奇想写一下多线程的例子,我试了C的pthread也试了其他的,最后觉得C++11的thread是真的方便,我就写一篇博客介绍一下,因为是QT实现的我就先从QT说起吧。
QT新建一个项目
qt建立一个工程,我建立的是图上的工程。剩下的部分全部点击下一步就好了,没什么特殊关照的。建立好工程之后大家一定要在.pro文件里边看看有没有
CONFIG += c++11
这段代码,这段代码的作用就是让qt可以支持c++11;qt的ui界面我放了三个label和一个button,就只是用来演示一下多线程的执行界面。
好了言归正传,C++11里边把多线程进行了整体的封装,就是说我们可以先引进thread库,随后再进行代码的撰写,我现在贴上QT的代码以供参考
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::photo1()
{
while(1)
{
for(auto i : {1,2,3,4,5,6,7,8})
{
QString S = QString::number(i);
QString s = ":/"+S+".jpg";
qDebug()<<s;
QImage n;
n.load(s);
ui->label->clear();
ui->label->setPixmap(QPixmap::fromImage(n));
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
update();
}
}
}
void MainWindow::photo2()
{
while(1)
{
for(auto i : {8,7,6,5,4,3,2,1})
{
QString S = QString::number(i);
QString s = ":/"+S+".jpg";
qDebug()<<s;
QImage m;
m.load(s);
ui->label_2->clear();
ui->label_2->setPixmap(QPixmap::fromImage(m));
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
update();
}
}
}
void MainWindow::photo3()
{
ui->label_3->setText("叫爸爸");
QPalette pa[4];
pa[0].setColor(QPalette::WindowText,Qt::red);
pa[1].setColor(QPalette::WindowText,Qt::blue);
pa[2].setColor(QPalette::WindowText,Qt::yellow);
pa[3].setColor(QPalette::WindowText,Qt::black);
QFont font("Microsoft YaHei",100);
ui->label_3->setFont(font);
while(1)
{
for(auto i : pa)
{
ui->label_3->setPalette(i);
std::this_thread::sleep_for(std::chrono::milliseconds(400));
}
}
}
void MainWindow::on_pushButton_clicked()
{
std::thread t1(&MainWindow::photo1 , this);
std::thread t2(&MainWindow::photo2 , this);
std::thread t3(&MainWindow::photo3 , this);
t3.detach();
t2.detach();
t1.detach();
qDebug()<<"this";
}
因为是一个简单的多线程讲解,我并没有使用互斥锁等等那些,其实我可以说一下互斥锁,在c++11中有一种类型叫原子数据类型,因为我使用的是atomic,所以我也就重点说一atomic的一些用法和讲解。
什么是原子数据类型?
从功能上看,原子数据类型不会发生数据竞争,可以直接用多线程中而不必我们用户对其添加互斥资源锁的类型。从实现上看可以将其理解为原子内部自己加上了互斥资源锁。
简单的代码各位自己看看吧,我没有和上边的qt代码关联起来啊,这是两个分开的工程。
#include<iostream>
#include<thread>
#include<atomic>
atomic_bool bisread = flase;
atomic_int count = 100;
void func1()
{
if(!bisread)
{
this_thread::yield();
}
while(count>0)
{
cout<<count--<<endl;
}
}
int main()
{
atomic_bool b;
list<thread>listthread;
for(auto i:{2,3,4,5,6,7,8,9})
{
listthread.push_back(thread(threadfunc1));
}
for(auto &th : listthread)
{
th.join();
}
}
以上就是原子数据类型了,有点跑题了,不过没关系,我们来看看我们的多线程运行结果吧。
先写这么点吧,如果有问题欢迎批评指正