1、头文件
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();
};
// MAINWINDOW_H
2、cpp
using namespace std;
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分钟某任务还没执行成功,则退出不再执行任务,回收所有内存【如数据库操作时数据库异常】