多线程:
thread_local
每个线程都会有自己的一份数据,不会共享数据,避免竞争
volatile
告诉编译器每次取数据都要从内存里取
使用情况:
- 信号处理
- 内存映射相关
- 非本地跳转
std::atomic
定义操作为原子操作,不可被线程分开
接口
std::shread C++的线程类,但是不保证异步。std::async可以强制异步,可以指定两种异步方式: std::launch::async(使用新的线程异步执行任务)和std::launch::deferred(用当前线程执行,时间上会延后)
如果需要在调用线程和新线程之间同步数据可以用promise和future
std::promise
其作用是在一个线程t1中保存一个类型typename T的值,可供相绑定的std::future对象在另一线程t2中获取。
std::future
可以用来获取异步任务的结果,因此可以把它当成一种简单的线程间同步的手段。std::future对象通常通过某个Provider创建,Provider在某个线程中设置共享状态的值,与该共享状态相关联的std::future对象通过get获得该值,如果该装填不为ready,则std::future::get会阻塞当前调用的人,知道Provider设置了共享状态的值为ready,get会返回异步任务的值或异常。
实例: #include <iostream> #include <future> #include <chrono> void Thread_Fun1(std::promise<int> &p) { //为了突出效果,可以使线程休眠5s std::this_thread::sleep_for(std::chrono::seconds(5)); int iVal = 233; std::cout << "传入数据(int):" << iVal << std::endl; //传入数据iVal p.set_value(iVal); } void Thread_Fun2(std::future<int> &f) { //阻塞函数,直到收到相关联的std::promise对象传入的数据 auto iVal = f.get(); //iVal = 233 std::cout << "收到数据(int):" << iVal << std::endl; } int main() { //声明一个std::promise对象pr1,其保存的值类型为int std::promise<int> pr1; //声明一个std::future对象fu1,并通过std::promise的get_future()函数与pr1绑定 std::future<int> fu1 = pr1.get_future(); //创建一个线程t1,将函数Thread_Fun1及对象pr1放在线程里面执行 std::thread t1(Thread_Fun1, std::ref(pr1)); //创建一个线程t2,将函数Thread_Fun2及对象fu1放在线程里面执行 std::thread t2(Thread_Fun2, std::ref(fu1)); //阻塞至线程结束 t1.join(); t2.join(); return 1; }
C++20支持协程
std::mutex 互斥量,表示之后的代码段同时只能由一个线程访问
lock_guard是一种在作用域内可以控制可锁对象所有权的类型
特点:
(1) 创建即加锁,作用域结束自动析构并解锁,无需手工解锁
(2) 不能中途解锁,必须等作用域结束才解锁
(3) 不能复制
std::unique_lock 可以实现尝试获得锁, 如果当前以及被其它线程锁定, 则延迟直到其它线程释放, 然后才获得锁.
特点:
(1) 创建时可以不锁定(通过指定第二个参数为 std::defer_lock),而在需要时再锁定
(2) 可以随时加锁解锁
(3) 作用域规则同 lock_grard,析构时自动释放锁
(4) 不可复制,可移动
(5) 条件变量需要该类型的锁作为参数(此时必须使用 unique_lock)
std::mutex g_mutex;
std::lock_guard<std::mutex> guard(g_mutex);//可以及时进入和释放互斥量
实例: #include <chrono> #include <thread> #include <mutex> bool flag; std::mutex m; void wait_for_flag() { std::unique_lock<std::mutex> lk(m); // 这里采用std::unique_lock而非std::lock_guard. std::unique_lock可以实现尝试获得锁, 如果当前以及被其它线程锁定, 则延迟直到其它线程释放, 然后才获得锁. while(!flag) { lk.unlock(); // 解锁互斥量 std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 休眠100ms,在此期间,其它线程可以进入互斥量,以便更改flag标记。 lk.lock(); // 再锁互斥量 } }
std::condition_variable(条件变量)
源自博客:https://blog.csdn.net/qq_23350817/article/details/116460138
标签:std,include,get,lock,C++,future,线程,多线程 From: https://www.cnblogs.com/PireannUE/p/17436464.html