C++std::thread调⽤带参数和返回值的函数
⼀、线程调⽤的函数含有参数
多线程中的函数参数如果为引⽤必须使⽤std::ref(函数式编程的参数默认使⽤拷贝⽅式),多线程中的函数参数如果为IO(socket应该也需要,没有测试过)必须使⽤移动语义(std::move),避免多个对象同时读写同⼀个IO缓冲
点击查看代码
⼆、线程调⽤成员函数
点击查看代码
三、多线程执⾏含有返回值的函数,获取函数返回值
1.将函数的返回值设置为输出参数
2.使⽤lambda表达式获取函数返回值
点击查看代码
3.使⽤std::future、std::promise和packaged_task
std::async和std::future的使⽤
std::async()与std::thread()最明显的不同就是async只是创建异步任务,不⼀定创建线程。async()默认创建线程,可以设置第⼀个参数来决定是否创建线程。
async函数原型
点击查看代码
std::promise和std::future的使⽤
promise作为参数应该以引⽤的形式传⼊(),因此需要使⽤
指针调用成员函数
future和promise的作⽤是在不同线程之间传递数据。使⽤指针也可以完成数据的传递,但是指针⾮常危险,因为互斥量不能阻⽌指针的访问;⽽且指针的⽅式传递的数据是固定的,如果更改数据类型,那么还需要更改有关的接⼝,⽐较⿇烦;promise⽀持泛型的操作,更加⽅便编程处理。std::promise的作⽤就是提供⼀个不同线程之间的数据同步机制,它可以存储⼀个某种类型的值,并将其传递给对应的future,即使这个future不在同⼀个线程中也可以安全的访问到这个值。
点击查看代码
std::packaged_task和std::future的使⽤
std::packaged_task的作⽤就是提供⼀个不同线程之间的数据同步机制,std::packaged_task本⾝和线程没有关系,它只是关联了⼀个std::future的仿函数。需要显式的调⽤或者传递给std::thread进⾏异步调⽤,所以它更灵活(可以选择什么时候开始任务)。
std::packaged_task 对象内部包含了两个最基本元素
被包装的任务(stored task),任务(task)是⼀个可调⽤的对象,如函数指针、成员函数指针或者函数对象
共享状态(shared state),⽤于保存任务的返回值,可以通过 std::future 对象来达到异步访问共享状态的效果。
点击查看代码
async、promise、paceaged_task三者的区别与联系
⽤ std::async 来做简单的事情,例如异步执⾏⼀个任务。但是要注意 std::future 析构阻塞的问题。
std::packaged_task 能够很轻松的拿到 std::future,选择是否配合 std::thread 进⾏异步处理。同时没有析构阻塞的问题。
std::promise 是三者中最底层的能⼒,可以⽤来同步不同线程之间的消息