Multithreading 如果尚未持有读/写锁,则获取读/写锁
在GLib中,是否有一个操作告诉它“如果你还没有持有锁,就获取锁”?同一线程是否可以获取两次锁(使第二次获取成为no op,或要求释放两次),或者测试它是否已经持有某个特定的锁 假设我的代码中有以下函数:Multithreading 如果尚未持有读/写锁,则获取读/写锁,multithreading,glib,Multithreading,Glib,在GLib中,是否有一个操作告诉它“如果你还没有持有锁,就获取锁”?同一线程是否可以获取两次锁(使第二次获取成为no op,或要求释放两次),或者测试它是否已经持有某个特定的锁 假设我的代码中有以下函数: void func_a() { //g_rw_lock_writer_lock(&shared_data->rw_lock); mess_with_data(shared_data); func_b(); //g_rw_lock_writer_un
void func_a() {
//g_rw_lock_writer_lock(&shared_data->rw_lock);
mess_with_data(shared_data);
func_b();
//g_rw_lock_writer_unlock(&shared_data->rw_lock);
}
void func_b() {
//g_rw_lock_writer_lock(&shared_data->rw_lock);
mess_with_data_again(shared_data);
//g_rw_lock_writer_unlock(&shared_data->rw_lock);
}
假设:
指向共享数据结构,需要在线程之间同步访问shared_data
是同步访问的读/写锁shared_data->rw_lock
- 可以从外部调用
和func_a()
func_b()
和mess\u with_data()
不是线程安全的,因此调用方需要在调用它们之前对数据持有写锁mess\u with_data\u()
- 它们不仅仅是单个函数调用,而是语句行,因此将
的主体复制到func_b()
中是不可取的(代码重复,可维护性差)func_a()
和func_a()
的调用方无法直接访问锁,因此需要在发动机罩下进行锁定func_b()
- 将
(无锁定/解锁)的函数体提取到由func_b()
和func_a()
调用的单独辅助函数中不是一个选项(它们分布在多个模块中,函数调用之间存在抽象层,事实上,func_()
不是直接按名称调用func_a()
,而是一个指针,恰好解析为func\u b()
)func\u b()
我该如何解决这个问题呢?第一件事:你要找的单词是“” 虽然
GMutex
明确提到互斥锁是否是递归的未定义,但AFAIKGRWLock
只是忽略了写入锁是否是递归的(读取器端是递归的)
如果深入研究一下实现,您将看到在POSIX上,GRWLock是使用pthread\u rwlock\t
实现的(“如果调用线程在调用时持有读写锁(无论是读锁还是写锁),则结果是未定义的。”)。所以基本上不,GRWLock
对于writer锁不是递归的
至于如何解决您的问题,我的第一个建议是让mess\u与\u数据
和mess\u与\u数据
再次获取并释放锁。请记住,您应该只持有必要的锁,而不再持有
如果出于某种原因(比如您可能没有访问该代码的权限),您可以使用递归锁,或者将编写器操作限制为一个线程,并使用队列与之通信
也可以重构mess\u与\u数据
和mess\u与\u数据
以使它们不需要锁,但这可能是可能的,也可能是不可能的,并且可能是相当困难的