std::async
std::async用于创建异步任务,实际上就是创建一个线程执行相应任务,默认立即开始执行。
std::async就是异步编程的高级封装,std::async的操作,其实相当于封装了std::promise、std::packaged_task加上std::thread,基本上可以代替std::thread 的所有事情。
#include <stdio.h>
#include <stdlib.h>
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex
#include <future> // std::future
int thread_task()
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << "thread_task" << std::endl;
return 0;
}
int main()
{
std::async(thread_task);
return 0;
}
std::launch::deferred参数
如果对std::async使用该参数,那么这个任务将变成同步任务,不会立即执行,直到std::future类对象调用get()或者wait()时才会开始执行,而且不会创建子线程,会直接在本线程执行。
#include <stdio.h>
#include <stdlib.h>
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex
#include <future> // std::future
int thread_task()
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << "thread_task" << std::endl;
return 0;
}
int main()
{
std::future<int> result = std::async(std::launch::deferred, thread_task);
//std::cout << result.get() << std::endl;
return 0;
}
std::launch::async参数
这是std::async的默认参数,即创建一个子线程并立即开始执行。
#include <stdio.h>
#include <stdlib.h>
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex
#include <future> // std::future
int thread_task()
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << "thread_task" << std::endl;
return 0;
}
int main()
{
std::future<int> result = std::async(std::launch::async, thread_task);
//std::cout << result.get() << std::endl;
return 0;
}
std::future
std::async异步任务可以返回一个std::future对象,可用来保存子线程入口函数的返回值。
std::async、std::packaged_task 或 std::promise都能提供一个std::future对象给该异步操作的创建者。
#include <stdio.h>
#include <stdlib.h>
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex
#include <future> // std::future
int thread_task()
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << "thread_task" << std::endl;
return 0;
}
int main()
{
std::future<int> result = std::async(thread_task);
std::cout << result.get() << std::endl;
return 0;
}
使用std::future类的get()函数,可以阻塞等待子线程返回获取返回值.
std::future类的wait()函数,可以阻塞等待子线程执行结束,本身不返回结果。
get()函数职能调用一次,不可调用多次,调用多次会导致程序异常退出。
std::packaged_task
std::packaged_task 包装一个可调用的对象,并且允许异步获取该可调用对象产生的结果,从包装可调用对象意义上来讲,std::packaged_task 与 std::function 类似,只不过 std::packaged_task 将其包装的可调用对象的执行结果传递给一个 std::future 对象(该对象通常在另外一个线程中获取 std::packaged_task 任务的执行结果)。
std::packaged_task 对象内部包含了两个最基本元素:一、被包装的任务(stored task),任务(task)是一个可调用的对象,如函数指针、成员函数指针或者函数对象;二、共享状态(shared state),用于保存任务的返回值,可以通过 std::future 对象来达到异步访问共享状态的效果。
#include <stdio.h>
#include <stdlib.h>
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex
#include <future> // std::future
int thread_task(int i)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << "thread_task" << i << std::endl;
return 0;
}
int main()
{
std::packaged_task<int(int)> pack(thread_task);
std::thread mythread(std::ref(pack), 5);
mythread.join();
std::future<int> result = pack.get_future();
std::cout << result.get() << std::endl;
return 0;
}
std::packaged_task对象还可以直接调用,类似函数调用,如上例中使用pack(5)。
std::promise
我们可以在某个线程中对该类对象进行赋值,然后可以在其它线程中取出其值。
#include <stdio.h>
#include <stdlib.h>
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex
#include <future> // std::future
int thread_task(std::promise<int>& pro, int i)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << "thread_task" << i << std::endl;
pro.set_value(i);
return 0;
}
int main()
{
std::promise<int> pro;
std::thread mythread(thread_task, std::ref(pro), 5);
mythread.join();
std::future<int> result = pro.get_future();
std::cout << result.get() << std::endl;
return 0;
}
set_value()只能被调用一次,多次调用会导致程序异常。
get()也只能被调用一次,多次调用会导致程序异常。
std::share_future()对象可以多次被get()。
#include <stdio.h>
#include <stdlib.h>
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex
#include <future> // std::future
int thread_task(std::promise<int>& pro, int i)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << "thread_task" << i << std::endl;
pro.set_value(i);
return 0;
}
int main()
{
std::promise<int> pro;
std::thread mythread(thread_task, std::ref(pro), 5);
mythread.join();
std::future<int> result = pro.get_future();
std::future_status status = result.wait_for(std::chrono::milliseconds(1000));
if (std::future_status::ready == status)
{
//线程已成功返回
}
else if (std::future_status::timeout == status)
{
//wait_for的时间已结束,线程仍未成功返回
}
else if (std::future_status::deferred == status)
{
//如果std::async的第一个参数设置为std::launch::deferred
//则该线程会直到std::future对象调用wait()或get()时才会执行
//这种情况就会满足
}
std::cout << result.get() << std::endl;
return 0;
}