Multithreading 如果尚未持有读/写锁,则获取读/写锁

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

在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_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
明确提到互斥锁是否是递归的未定义,但AFAIK
GRWLock
只是忽略了写入锁是否是递归的(读取器端是递归的)

如果深入研究一下实现,您将看到在POSIX上,GRWLock是使用
pthread\u rwlock\t
实现的(“如果调用线程在调用时持有读写锁(无论是读锁还是写锁),则结果是未定义的。”)。所以基本上不,
GRWLock
对于writer锁不是递归的

至于如何解决您的问题,我的第一个建议是让
mess\u与\u数据
mess\u与\u数据
再次获取并释放锁。请记住,您应该只持有必要的锁,而不再持有

如果出于某种原因(比如您可能没有访问该代码的权限),您可以使用递归锁,或者将编写器操作限制为一个线程,并使用队列与之通信

也可以重构
mess\u与\u数据
mess\u与\u数据
以使它们不需要锁,但这可能是可能的,也可能是不可能的,并且可能是相当困难的