explorer

万丈高楼平地起,勿在浮沙筑高台

0%

除了用户主动使用互斥锁来保护共享数据,也可以在设计共享数据结构的时候让其可以被并发的访问。

这样子的数据结构对用户就相对更加的友好,对于用户来说它就是多线程安全的。

但不管怎么说,这种数据结构在被并发访问的时候,其实是将多个线程的访问进行了串行化。那么就需要将互斥的区间设计的越小越好,以达到尽量高的并发性。

阅读全文 »

避免data race的底层方法有 3 种:

  1. 使用互斥机制,保证访问共享数据的原子性
  2. 使用无锁编程
  3. 使用事务机制(如同数据库一样,将多个操作做成日志形式,一旦日志被打断则重新开始)

而互斥机制是相对简单易用的方式。

阅读全文 »

为了兼顾性能和功能性,有些类会提供拷贝和移动两个版本:

1
2
3
4
5
6
7
8
9
class Widget {
public:
void addName(const std::string& newName) // take lvalue;
{ names.push_back(newName); } // copy it
void addName(std::string&& newName) // take rvalue;
{ names.push_back(std::move(newName)); } // move it;
private:
std::vector<std::string> names;
};

使用完美转发来实现一个简易版本:

1
2
3
4
5
6
7
8
class Widget {
public:
template<typename T> // take lvalues
void addName(T&& newName) // and rvalues;
{ // copy lvalues,
names.push_back(std::forward<T>(newName)); // move rvalues;
}
};

但通用引用可以接收各种类型的参数,这在传入错误的参数时,编译器的报错信息会异常繁琐。其实还有更好的选择。

阅读全文 »

lambda 使得 c++ 更有魅力,使用 lambda 可以创建一个可调用的对象,一般用于以下场合:

  1. 快速创建一个简短的函数,仅在父函数中使用,避免繁琐的创建成员函数的过程。
  2. 为标准库的算法(std::find_if,std::sort 等),优雅的创建一个可调用对象。
  3. 快速为标准库创建删除器,比如std::unique_ptr,std::shared_ptr
阅读全文 »