我可以在 std::shared_mutex 上使用 std::shared_lock 更改数据吗?
Can I change data with a std::shared_lock on a std::shared_mutex?
我有多个缓冲区与多个读取器/写入器线程共享,不同的写入器以不同的方式更改数据。
例如,Writer1 仅附加新数据,而 Writer2 扩展缓冲区的大小(重新分配内存和移动数据(。
如果我放置单个互斥锁来同步对数据的所有访问,性能可能不会更好,因为大多数读取器只需要读取单个缓冲区,而大多数编写器只需要将一小段数据写入单个缓冲区。
如果我为每个缓冲区准备一个互斥锁,线程之间的锁定/解锁关系将更加复杂。
现在我想确认一件事:
如果编写器仅使用互斥锁上的shared_lock更改数据,则其他写入器是否会在同一互斥锁上看到带有 unique_lock/shared_lock 的脏数据?
我编写了一个实验程序如下,看起来没有错误,但我仍然不敢在产品中使用它。
atomic_bool g_abShouldRun = true;
sem_t g_semDoIt1;
sem_t g_semDone1;
sem_t g_semDoIt2;
sem_t g_semDone2;
shared_mutex g_mutex;
int g_iX = 3, g_iY = 9, g_iR1 = 1, g_iR2 = 3;
void writer() {
std::srand( 8 );
while( g_abShouldRun ) {
sem_wait( &g_semDoIt1 );
while( rand() % 8 != 0 )
;
{
shared_lock<shared_mutex> lk( g_mutex );
g_iX *= 2;
g_iY *= 2;
}
sem_post( &g_semDone1 );
};
};
void reader() {
std::srand( 8 );
while( g_abShouldRun ) {
sem_wait( &g_semDoIt2 );
while( rand() % 8 != 0 )
;
{
unique_lock<shared_mutex> lk( g_mutex );
g_iR1 = g_iX;
g_iR2 = g_iY;
}
sem_post( &g_semDone2 );
};
};
int main( int argc, char** argv ) {
int iLasting = 10, iError = 0;
if( argc > 1 )
iLasting = atoi( argv[1] );
steady_clock::time_point tpEnd = steady_clock::now() + seconds( iLasting );
if( sem_init( &g_semDoIt1, 0, 0 ) || sem_init( &g_semDone2, 0, 0 ) ||
sem_init( &g_semDoIt2, 0, 0 ) || sem_init( &g_semDone2, 0, 0 ) ) {
cerr << "Failed to create semaphors." << endl;
return EXIT_FAILURE;
}
thread thd1( writer );
thread thd2( reader );
while( steady_clock::now() < tpEnd ) {
sem_post( &g_semDoIt1 );
sem_post( &g_semDoIt2 );
sem_wait( &g_semDone1 );
sem_wait( &g_semDone2 );
if( g_iR1 * 3 != g_iR2 )
++iError;
}
g_abShouldRun = false;
sem_post( &g_semDoIt1 );
sem_post( &g_semDoIt2 );
thd1.join();
thd2.join();
sem_destroy( &g_semDoIt1 );
sem_destroy( &g_semDoIt2 );
sem_destroy( &g_semDone1 );
sem_destroy( &g_semDone2 );
cout << "Error:" << iError << endl;
return EXIT_SUCCESS;
};
快速浏览一下,以下问题就会跳出来:
- 更改代码以在编写时使用
unique_lock
; - 更改代码以在读取时使用
shared_lock
; - 阅读时不要修改其他常见的全局变量——这实际上是在写,只是在不同的地方;
- 有多少 {
shared_mutex
s,函数使用unique_lock
,函数使用shared_lock
} 元组,您将与多个线程和多个缓冲区一起使用,您需要自己弄清楚 - 但它将在 1 和缓冲区数量之间。
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 引用 std::shared:ptr 以避免引用计数
- boost::shared_ptr和std::shared-ptr的同居
- 我可以用std::shared_ptr而不是boost::shared-ptr构建boost库吗
- std::dynamic_pointer_cast从基到派生的std::shared返回NULL
- QSharedPointer VS std::tr1::shared_ptr VS boost::tr1::shared