Multithread

  • 线程局部存储:thread_local, __declspec(thread), __thread
  • 强制内存读取:volatile
  • std::atomic
  • C++ 线程:
    • std::thread::join()
    • 如果需要在调用线程和新线程之间同步数据,则可以使用C++的std::promise和std::future等机制
    • 强制异步:std::async(std::launch::async | std::launch::deferred), return一个future
    • 上锁:
std::mutex mu0, mu1; // usually global

std::lock(mu0, mu1) // Ensures locking order and avoids deadlock 
std::lock_guard<mutex> locker0(mu0);
std::lock_guard<mutex> locker1(mu1);

std::unique_lock<mutex> locker(_mu, std::defer_lock); // Gives more flexibility, but more overhead

locker.lock();
// Operators that you want to protect
// ...
locker.unlock();

std::unique_lock<mutex> locker2 = std::move(locker); // Use move semantics to transfer the ownership
* std::condition_variable, notify_one, notify_all。提供更灵活的线程间的交流。Queue的例子

Move Semanitics and Right Value Reference

  • 相关知识点: 左值右值, 深浅拷贝
  • 推荐详细阅读: https://zhuanlan.zhihu.com/p/335994370

右值引用(Right Value Reference)的作用是什么?什么时候可以用到?

  • 右值引用是C++ 11引入的概念。常用于移动语义,主要目的是避免拷贝。在传统的左值传参的基础上,右值传参使这一行为更加灵活。
  • 移动语义:将拷贝的数据移动而非复制,避免多余的拷贝。例如:
// std::vector方法定义
void push_back (const value_type& val); //左值
void push_back (value_type&& val); // 右值
 
void emplace_back (Args&&... args); //右值

// 即可pushback 左值, 也可pushback 右值
std::vector<int> vec;
int a = 5;
vec.push_back(a); //左值
vec.push_back(5); //右值

为什么移动语义需要右值引用呢,为什么不能用左值引用呢?

  1. 第二个形参:不优雅,需要额外参数 Array& operator=(const Array& temp_array, bool move)
  2. 第一个形参:加 const 无法清空被拷贝者(temp_arrray), 不加 const 无法传入右值。

std::move和std::forward是干什么用的呢?

  • 将左值转为右值。std::foward主要用于模板编程的参数转发, 不常用到。