我可以使用 std::vector::swap 来修改共享向量吗?
Can I use std::vector::swap to modify a shared vector?
我正在开发多个线程读取访问具有大量(和大型(数据的单个std::vector
的软件。
我对多个头访问单个对象的复杂性有一些基本的了解,并且通过使用互斥锁可以大大简化事情。
就我而言,修改现有对象比复制它要昂贵得多。所以我正在考虑创建一个副本,修改副本(同时不持有互斥锁(和 然后将其交换回共享对象。
我不能使用 C++11,所以我无法访问移动操作,但我的理解是gcc
使用非常高效的std::vector::swap()
,可与移动操作(在速度方面(相媲美。
我在想这样的事情:
pthread_mutex_t mtx;
class bigdata_t { ... };
std::vector<bigdata_t> shared_vec; // accessed by multiple threads
void modify_bigdata()
{
pthread_mutex_lock(&mtx);
std::vector<bigdata_t> tmp_vec = shared_vec; // create copy
pthread_mutex_unlock(&mtx);
/*
* Here, apply expensive modifications to tmp_vec
*/
pthread_mutex_lock(&mtx);
shared_vec.swap(tmp_vec); // this is very fast and does not copy data
pthread_mutex_unlock(&mtx);
}
modify_bigdata()
仅由单个线程调用,因此这基本上是单编写器/多个读取器的方法。
它运行得非常快,但是将数据交换回共享向量感觉就像作弊一样。
我的问题是:
这种方法是否正确且线程安全?
假设您交换了整个向量,如果任何读取器线程在该向量内具有引用是非常危险的,因为在交换时,另一个向量很可能会被破坏,在这种情况下,来自读取器线程的任何引用都可能变得无效。
因此,每次您的读取器线程访问向量时,它们都需要一个锁。因此,使用交换在这里无济于事。它唯一可行的方法是通过使用某种多读取器 - 单写入器锁来确保没有读取器处于活动状态。
可能对您有用的是
std::vector<std::shared_ptr<bigdata_t>> shared_vec;
这样,您只需要正确同步指针交换并确保:
- 启动读取器线程或
- 您永远不会保留迭代器,并且对 Vector 的访问会正确同步。
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 在cuda线程之间共享大量常量数据
- 如何从具有移动语义的类对象中生成共享指针
- 在c代码之间共享数据的最佳方式
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 独立读取-修改-写入顺序
- 当系统的卷被修改时,如何修改WASAPI环回捕获卷
- 修改函数中的指针(将另一个指针作为参数传递)
- 为什么我可以通过引用修改常量返回
- 我可以使用 std::vector::swap 来修改共享向量吗?
- CMake:修改共享库时的冗余链接
- 使用 void 指针:void **ptr.. 如何修改共享内存的值?
- 是否要确保一个线程修改的任何数据类型的共享变量对其他线程可见
- 通知线程是否始终需要在修改期间锁定共享数据
- 使用多个线程迭代矢量(无数据共享或矢量修改)
- 即使我修改了LD_LIBRARY_PATH,也找不到我的共享库
- 为什么共享指针在修改后要失效
- 如果没有在互斥对象下修改共享原子变量,则不能正确发布