异步编程

  1. 1. C++异步编程
    1. 1.1. std::future和std::std::async
    2. 1.2. thread和future和promise

C++异步编程

std::future和std::std::async

方式一,使用C++实现异步编程的方法之一是通过std::future和std::std::async的配合:

1
2
3
4
5
6
7
8
9
10
11
12
13
int async_task(int x) {
_sleep(4000);
std::cout << "async_task start" << std::endl;
return x * x;
}

int main() {
std::future<int> future = std::async(std::launch::async, async_task, 10);
std::cout << "-------------------\n";
_sleep(3000);
std::cout << "async_task:\n" << future.get();
return 0;
}

std::launch::async标志要异步执行,std::launch::deferred标志同步执行。默认情况下,该值为std::launch::async|std::launch::deferred
上面这个例子中,输出为:

1
2
3
4
-------------------
async_task: //3S后输出
async_task start //4S后输出
100

程序会在get\作用域结束的时候等待异步任务运行的结果。加入,不调用get会怎么样呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int async_task(int x) {
_sleep(4000);
std::cout << "async_task start" << std::endl;
return x * x;
}

int main() {
std::future<int> future = std::async(std::launch::async, async_task, 10);
std::cout << "-------------------\n";
return 0;
}

//-------------------
//async_task start //4S后输出

程序依然会等待异步任务执行完毕后再结束。

thread和future和promise

方式二,使用thread,future和promise配合:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void async_task(std::promise<int> promise, int x) {
_sleep(3000);
promise.set_value(x * x);
}

int main(){
std::promise<int> promise;
std::future<int> future = promise.get_future();
std::thread t(async_task, std::move(promise), 10);
std::cout << "-------------------" << std::endl;
_sleep(1000);
std::cout << "async_task:\n" << future.get();
t.join();
return 0;
}

这样看起来会麻烦一些,还是需要通过std::future来传递异步任务的结果:

1
2
3
-------------------
async_task: //1S后输出
100 //3S后输出

如果把t.join();注释掉,程序输出如上,但是最后会抛出异常。也就是说,在执行到get的时候,程序会被阻塞,任务完成。
除此之外,std::promise还可以这样用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void async_task(std::promise<int> promise) {
std::future<int> future = promise.get_future();
std::cout << "async_task:" << future.get() << std::endl;
}

int main(){
std::promise<int> promise;
promise.set_value(100); //向异步任务传递数据
std::thread t(async_task, std::move(promise));
_sleep(2000);
std::cout << "-------------------" << std::endl;
t.join();
return 0;
}

/**
* async_task:100
------------------- //2S后输出
*/