(一) 线程概念、创建及传参
(二) 独占互斥锁–mutex,lock_guardy与其他mutex
(三) unique_lock替换lock_guardy
(四) 单例模式(Singleton)下的线程安全问题
(五) window临界区
(六) condition_variable条件变量
(七) std::async异步任务与std::future< >
(八) packaged_task< >与promise< >
(九) 原子操作atomic<>简介
std::async一般与std::future< >配套使用,前者异步或同步调用一个函数,返回一个future的模板类对象,在future中可以拿到入口函数的返回值
1.async异步调用函数,即创建一个线程,返回一个future模板类
2.async使用方式同thread 也可传入类函数(记住前面加&)
3.第一参数可以传入 std::launch::deferred标记,即延迟调用,等到get()才调用,且不创建线程,直接在主线程中执行(id一样),若不调用get或wait则不执行
4.不传入则默认是 std::launch::async | std::launch::deferred,则可能同步或异步
5.std::launch::async强制异步任务创建新线程,若系统资源紧张则通过thread创建失败导致崩溃
6.传入位或 (即同4)相当于开启两个标志位,是否开启线程或延迟由系统判定
int mythreadfuntion(int num)
{
cout << "mythreadfuntion异步执行 thread_id =" << this_thread::get_id() << endl;
std::chrono::milliseconds time(3000); //三秒钟
std::this_thread::sleep_for(time); //线程休眠
cout << "mythreadfuntion结束执行 thread_id =" << this_thread::get_id() << endl;
return num * 10;
}
std::future<int> result = std::async(mythreadfuntion,6); //创建一个线程开始执行返回值为int的参数传入6的mythreadfuntion
std::cout << "main主函数继续执行 " << endl; //不会堵塞主函数
std::cout << "async获取结果: result.get = " << async_result.get() << endl; //获取结果,若函数还没执行结束则堵塞
std::future<int> async_result = std::async(std::launch::deferred,mythreadfuntion, 6); //直接在主线程中执行(id一样),若不调用get或wait则不执行
std::cout << "main主函数继续执行 " << endl;
//result.wait(); //调用也会wait堵塞
std::cout << "async获取结果: result.get = " << async_result.get() << endl; //到此才调用mythreadfuntion
async与thread区别
thread强制创建新线程,若资源紧张则创建失败
thread不方便获取入口函数的返回值,可使用全局函数或 packaged_task获取
async创建异步任务,有系统判定是否可用创建线程,若不可以则在当前调用线程执行
async若延迟任务,线程中没有使用get或wait则不调用入口函数
async可用使用future.wait_for(3s)对任务状态进行判断
async可用future对入口函数返回值进行获取
线程数量最好控制在100-200
1.用于访问异步数据,即将来的数据
2.调用get()或wait()则等待子线程执行完才返回
3.不能多次调用get(),只能调用一次,除非用future_share
4.调用wait_for返回一个包含 超时,延迟,就绪三种枚举类型std::future_status
5.若async传入deferred,wait_for传入时间无效,程序不会等待,进入次调用get才执行函数
6.std::chrono::seconds(1)传入wait_for等待时长
7.vaile()返回一个布尔值,判定里面是否存在有效值
std::future<int> result = std::async(mythreadfuntion, 6); //创建一个线程开始执行
std::cout << "main主函数继续执行 " << endl;
std::future_status s = result.wait_for(std::chrono::seconds(1)); //返回一个枚举类型enum
if(s == future_status::timeout) //wait_for 1秒时超时
std::cout << "wait_for等待超时 " << endl;
else if(s == future_status::ready) //wait_for 4秒时准备
std::cout << "wait_for准备就绪" << endl;
else if (s == future_status::deferred) //async传入deferred且程序不会等待,进入次调用get才执行函数
std::cout << "wait_for延迟" << endl;
1.future由于get()不是复制赋值,而是值的移动,所以只能调用一次,调用后则已被清空
2.使用future创建shared_future两种方式
一种std::shared_future result_s (std::move(result));
另一种std::shared_future result_s (result.share());
3.用get()获取值,可以调用多次
std::shared_future<int> result_s;
if(result.valid()) //判断是否有有效值
result_s = result.share(); //创建共享
std::cout << "async获取结果: result_s.get = " << result_s.get() << result_s.get() << endl; //调用get则堵塞,若注释此句主函数将继续执行,但不会退出(可能不安全)
#include
#include
#include
#include
using namespace std;
int mythreadfuntion(int num)
{
cout << "mythreadfuntion异步执行 thread_id =" << this_thread::get_id() << endl;
std::chrono::milliseconds time(3000); //三秒钟
std::this_thread::sleep_for(time); //线程休眠
cout << "mythreadfuntion结束执行 thread_id =" << this_thread::get_id() << endl;
return num * 10;
}
int main()
{
std::cout << "main主函数id = " << this_thread::get_id() << endl;
std::future<int> result = std::async(mythreadfuntion, 6); //创建一个线程开始执行
std::cout << "main主函数继续执行 " << endl;
std::future_status s = result.wait_for(std::chrono::seconds(1)); //返回一个枚举类型enum
if(s == future_status::timeout) //wait_for 1秒时超时
std::cout << "wait_for等待超时 " << endl;
else if(s == future_status::ready) //wait_for 4秒时准备
std::cout << "wait_for准备就绪" << endl;
else if (s == future_status::deferred) //async传入deferred且程序不会等待,进入次调用get才执行函数
std::cout << "wait_for延迟" << endl;
std::shared_future<int> result_s;
if(result.valid()) //判断是否有有效值
result_s = result.share(); //创建共享
std::cout << "async获取结果: result_s.get = " << result_s.get() << result_s.get() << endl; //调用get则堵塞,若注释此句主函数将继续执行,但不会退出(可能不安全)
std::cout << "main主函数结束 " << endl;
}