#pragma once
#include <QtWidgets/QWidget>
#include "ui_future_test.h"
#include <future>
class future_test : public QWidget
{
Q_OBJECT
public:
future_test(QWidget *parent = Q_NULLPTR);
public slots:
void on_pushbuton_clicked();
void on_pushbuton_2_clicked();
void on_pushbuton_3_clicked();
private:
QString doTask();
void doTask2();
void doTask3();
private:
Ui::future_testClass ui;
std::promise<QString> m_p;
};
#include "future_test.h"
#include <chrono>
#include <thread>
#include <QDebug>
#include <QThread>
future_test::future_test(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
}
void future_test::on_pushbuton_clicked()
{
qDebug() << "main thread:" << QThread::currentThreadId() << endl;
auto f= std::async(std::launch::async, &future_test::doTask, this);//参数std::launch::async指定另外一个线程去执行任务
//auto f = std::async(&future_test::doTask, this);//异步任务和主线程同一个线程上
//f.wait();
qDebug() << f.get() << endl;//发生阻塞直到future就绪
}
QString future_test::doTask()
{
qDebug() << "task thread:" << QThread::currentThreadId() << endl;
std::this_thread::sleep_for(std::chrono::seconds(3));
qDebug() << "do task over" << endl;
return QString("111111111");
}
void future_test::on_pushbuton_2_clicked()
{
//std::packaged_task的模板函数签名要和任务的函数签名一致,不需要太严格
qDebug() << "main thread:" << QThread::currentThreadId() << endl;
//方式一;单线程的
// std::function<QString()> func = std::bind(&future_test::doTask, this);
// std::packaged_task<QString()> tasks(func);//可以被分装入function对象中调用
// //std::packaged_task<QString()> tasks(std::bind(&future_test::doTask, this));
// tasks();
// auto f = tasks.get_future();//返回一个future对象,调用这个对象的get函数阻塞直到就绪
// qDebug() << f.get() << endl;//发生阻塞直到future就绪
//方式二:自己的线程中完成任务
std::thread taskThread(&future_test::doTask2, this);//任务线程如何返回结果给主线呢在未设置全局变量的情况下???
taskThread.join();
}
void future_test::doTask2()
{
//lambda表达式中封装了要完成的任务
std::packaged_task<QString()> tasks([]{
qDebug() << "task thread:" << QThread::currentThreadId() << endl;
std::this_thread::sleep_for(std::chrono::seconds(3));
qDebug() << "do task over" << endl;
return QString("111111111");
});
tasks();
auto f = tasks.get_future();//返回一个future对象,调用这个对象的get函数阻塞直到就绪
qDebug() << f.get() << endl;//发生阻塞直到future就绪
}
void future_test::on_pushbuton_3_clicked()
{
try
{
m_p.set_value("22222");//全局变量第二次失败??
}
catch (...)
{
m_p.set_exception(std::current_exception());
}
std::thread taskThread(&future_test::doTask3, this);//任务线程如何返回结果给主线呢在未设置全局变量的情况下???
taskThread.join();
}
void future_test::doTask3()
{
qDebug() << "do task over" << endl;
auto f= m_p.get_future();
qDebug() << f.get() << endl;//发生阻塞直到future就绪
}