所谓双buffer技术,其实就是准备两个Obj,一个用来读,一个用来写。写完成之后,原子交换两个Obj;之后的读操作,都放在交换后的读对象上,而原来的读对象,在原有的“读操作”完成之后,又可以进行写操作了。
但是,这里有两个问题:
1.“原子交换”如何做?
2.如何判断,原来的读对象上的读取操作都结束了?
先看第二个问题,可以通过shared_ptr的use_count()获得其引用计数,来判断当前是否还有其他线程在读取这个Obj;
但是,shared_ptr的读写无法做到原子操作——shared_ptr的引用计数是原子的,但是shared_ptr本身不是。
这时,可以换个思路。我们将两个shared_ptr对象放到一个数组中,用一个原子的下标表示当前的读对象,此时“原子交换”,只需要原子赋值下标即可。
伪代码如下:
std::vector<shared_ptr<Obj>> obj_buffers;
std::atomic_size_t curr_idx;
// write thread
{
size_t prepare = 1 - curr_idx.load();
if (obj_buffers[prepare].use_count() > 1) {
continue;
}
obj_buffers[prepare]->load();
curr_idx = prepare;
}
// read thread
{
shared_ptr<Obj> tmp = obj_buffers[curr_idx.load()];
useObj(tmp);
}
这里需要注意的是,C++的基本类型并不保证原子性,所以这里需要使用C++11中新增的std::atomic原子类型作为下标。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。