在GLib中,是否有一项操作告诉它“如果您尚未持有该锁,则先获取它”?同一线程可以两次获取一个锁(使第二次获取成为无操作,或者要求将其释放两次)或测试它是否已经持有特定的锁?
假设我的代码中具有以下功能:
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_with_data()
和mess_with_data_again()
不是线程安全的,因此调用方需要在对数据进行写锁之前对其进行调用func_b()
的主体复制到func_a()
中不是一种选择(代码重复,可维护性差)func_a()
和func_b()
的调用者无法直接访问该锁,因此需要在后台进行锁定func_b()
的函数体(不进行锁定/解锁)提取到func_a()
和func_()
分别调用的单独的辅助函数中是不可行的(它们分散在多个模块之间,并且函数调用之间存在抽象层-实际上,func_a()
并不是直接按名称调用func_b()
,而是恰好解析为func_b()
的指针)。我该如何解决?
答案 0 :(得分:1)
首先,要寻找的单词是“ recursive”。
虽然GMutex
明确提到互斥体是否是递归的,但AFAIK GRWLock
只是忽略了 writer 锁是否是递归的(读者方面)是递归的。)
如果稍微深入了解实现,您会发现在POSIX上GRWLock
是使用pthread_rwlock_t
,which needn't be recursive实现的(“如果调用线程持有调用时具有读写锁定(无论是读取锁定还是写入锁定)。”)。因此,基本上没有,GRWLock
对于写程序锁不是递归的。
关于如何解决您的问题,我的第一个建议是让mess_with_data
和mess_with_data_again
自己获取并释放锁。请记住,您只应将锁保持必要的时间,而不必再保持时间。
如果由于某种原因(例如您可能无法访问该代码)而不选择该选项,则可以使用递归锁,或者将编写器操作限制为一个线程并使用队列与之通信。
还可以重构mess_with_data
和mess_with_data_again
,以便它们不需要锁,但这可能或不可能,而且很困难。