C++多线程进阶
原创
©著作权归作者所有:来自51CTO博客作者开始喜欢风的原创作品,请联系作者获取转载授权,否则将追究法律责任
C++多线程进阶
- unique_lock三大参数对象
- condition_variable条件变量
- async&future异步任务
- packaged_task任务打包
- promise赋值取用
unique_lock三大参数对象
adopt_lock:表示已经lock了,无需再次lock了
#include <mutex>
#include <thread>
#include <iostream>
std::mutex my_mutex;
void func01() {
my_mutex.lock();
std::lock_guard<std::mutex> g(my_mutex, std::adopt_lock);
}
int main() {
thread t1(func01);
return 0;
}
try_to_lock():再次之前没有锁,这个函数进行锁,如果锁了,返回异常
#include <mutex>
#include <thread>
#include <iostream>
std::mutex my_mutex;
void func01() {
// my_mutex.lock();加了锁会报错
std::lock_guard<std::mutex> g(my_mutex, std::try_to_lock);
if (g.owns_lock()) {
// 查看是否拿到了锁
}
}
int main() {
thread t1(func01);
return 0;
}
condition_variable条件变量
线程执行的条件关键字
wait():等待条件满足才执行下面的数据。如果第二个参数是false,那么wait()将解锁互斥量,并堵塞到本行,堵塞到其他某个线程调用notify_one成员函数为止,此后,wait不断尝试获取互斥量锁
#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>
std::mutex my_mutex;
std::condition_variable my_con;
int a = 1;
void func01() {
for (int i = 0; i < 1000; i++) {
std::lock_guard<std::mutex> g(my_mutex);
my_con.wait(g, [&a] {
if (a == 1) {
return true;
}
});
}
}
notify_one():尝试唤醒一个正在wait的线程
void func02() {
for (int i = 0; i < 1000; i++) {
std::lock_guard<std::mutex> g(my_mutex);
std::cout << "yes" << std::endl;
notify_one();
}
}
notify_all():尝试唤醒多个正在wait的线程
#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>
std::mutex my_mutex;
std::condition_variable my_con;
int a = 1;
void func01() {
for (int i = 0; i < 1000; i++) {
std::lock_guard<std::mutex> g(my_mutex);
my_con.wait(g, [&a] {
if (a == 1) {
return true;
}
});
}
}
void func02() {
for (int i = 0; i < 1000; i++) {
std::lock_guard<std::mutex> g(my_mutex);
std::cout << "yes" << std::endl;
notify_all();
}
}
int main(int argc, char const* argv[]) {
std::thread t1_1(func01);
std::thread t1_2(func01);
std::thread t2(func02);
t1.join();
t2.join();
return 0;
}
async&future异步任务
async, future创建后台任务并返回值,async是个函数模板,用来启动一个异步任务(线程入口函数),返回一个future对象
#include <iostream>
#include <thread>
#include <future>
int func() {
std::cout << std::this_thread::get_id() << std::endl;
return 5;
}
int main(int argc, char const* argv[]) {
std::cout << std::this_thread::get_id() << std::endl;
// 此程序意味着该线程在async处就开始创建
std::future<int> result = std::async(func);
std::cout << result.get() << std::endl;
return 0;
}
/*output:
25224
68260
5
*/
参数:std::launch::deferred
意义:表示线程入口函数调用被延迟到std::future的wait()或者get()函数调用时才执行,如果没有wait或者get,线程不会被创建;如果创建了,也是在主线程调用的线程入口函数.
#include <iostream>
#include <thread>
#include <future>
int func() {
std::cout << std::this_thread::get_id() << std::endl;
return 5;
}
int main(int argc, char const* argv[]) {
std::cout << std::this_thread::get_id() << std::endl;
std::future<int> result = std::async(func);
// 此程序意味着该线程在async处就开始创建
std::cout << result.get() << std::endl;
return 0;
}
/*output:
74264 如果创建了,也是在主线程调用的线程入口函数.
74264
5
*/
参数:std::launch::async
意义:与默认函数相同
packaged_task任务打包
#include <iostream>
#include <future>
#include <thread>
/*
打包方法:
std::packaged_task<返回值(参数)> 类对象(入口函数);
*/
int func(int arg) {
int num = arg + 1;
std::cout << "this is a thread: " << std::this_thread::get_id() << std::endl;
return num;
}
int main() {
std::packaged_task<int(int)> mypack(func);
// 以类对象作为线程调用的入口
std::thread t1(std::ref(mypack), 1);
t1.join();
std::future<int> res = mypack.get_future();
std::cout << res.get() << std::endl;
// 把打包的类对象放入容器中
std::vector<std::packaged_task<int(int)>> mytask;
mytask.push_back(std::move(mypack));
// 把打包的类对象从容器中拿出
std::packaged_task<int(int)> mypt;
auto iter = mytask.begin();
mypt = std::move(*iter);
mytask.erase(iter);
// 执行类对象打包的函数
std::thread t2(std::ref(mypt), 1);
t2.join();
std::future<int> re = mypt.get_future();
std::cout << re.get() << std::endl;
return 0;
}
promise赋值取用
我们能够在某个线程中给他赋值,然后我们可以在其他线程中,把这个值取出来用
#include <iostream>
#include <thread>
#include <future>
void func(std::promise<int>& tp, int num) {
int res = 10;
tp.set_value(res);
return;
}
void func(std::future<int>& tp) {
int res = 10;
tp.set_value(res);
return;
}
int main() {
std::promise<int> mypro;
std::thread t1(func, std::ref(mypro), 180);
t1.join();
// 获取结果值
std::future<int> ful = mypro.get_future();
// auto res = ful.get();
// std::cout << res << std::endl;
// 也可以利用future的返回值做参数
std::thread t2(func, std::ref(ful));
t2.join();
// 获取结果值
std::future<int> fup = ful.get_future();
return 0;
}
溜了溜了,下一篇重点来介绍介绍future的成员函数