C++的std::future使用

1、头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDebug>
#include <QDomDocument>

using namespace std;
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    Ui::MainWindow *ui;

    bool is_prime(int x)
    {
        for (int i = 2; i < x; ++i)
            if (x % i == 0)
                return false;
        return true;
    }

    void toUi();
    void toDb();
private slots:

    void on_pushButton_clicked();

};

#endif // MAINWINDOW_H

2、cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDialog>

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

#include<stdio.h>
#include<math.h>
#include <memory>
#include <future>


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::toUi()
{
    qDebug()<<"begin do ui";
    qDebug()<<"doing ui";
    qDebug()<<"end do ui";
}

void MainWindow::toDb()
{
    qDebug()<<"begin do db";

    std::future < bool > fut = std::async(&MainWindow::is_prime, this, 444444443);

    // do something while waiting for function to set future:
    //    qDebug() << "checking, please wait";
    //    std::chrono::milliseconds span(100);
    //    while (fut.wait_for(span) == std::future_status::timeout)
    //        qDebug() << '.' << (int)fut.wait_for(span);

    qDebug()<<"doing db";

    bool x = fut.get();         // retrieve return value
    qDebug() << "\n444444443 " << (x ? "is" : "is not") << " prime.\n";



    qDebug()<<"end do db";
}

//入口函数
void MainWindow::on_pushButton_clicked()
{
    qDebug()<<"to do ui";
    std::thread uiThread(&MainWindow::toUi, this);
    uiThread.detach();


    qDebug()<<"to do db";
    std::thread dbThread(&MainWindow::toDb, this);
    dbThread.detach();

    qDebug()<<"other work" <<111111;
}

 

3、结果

 

 环境是Qt

 

 

说明:

①、主线程是可能涉及界面操作或者主要流程管理,不能阻塞;

②、需要通过std::thread出一个子线程,用于管理业务线程,业务线程通过std::async生成业务线程,在此线程里可以wait等阻塞;

③、在业务线程里做耗时操作,如操作数据库等。

④、通过fut.get()函数返回异步运行结果,如果没有完成是会阻塞直到完成;

⑤、通过fut.wait_for来定周期判断当前任务是否完成,返回值有三个

  enum class future_status
  {
    ready,    //完成任务
    timeout,   //未完成任务
    deferred    //还未执行任务
  };

可通过这来设置超时不再执行任务,如超过1分钟某任务还没执行成功,则退出不再执行任务,回收所有内存【如数据库操作时数据库异常】

 

posted @ 2021-07-19 18:04  朱小勇  阅读(402)  评论(0编辑  收藏  举报