如果尚未持有,则获取 read/write 锁

Acquire a read/write lock if not already held

在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);
}

假设:

我该如何解决这个问题?

首先要注意的是:您要查找的词是“recursive”。

虽然 GMutex 明确提到互斥锁是否递归是未定义的,但 AFAIK GRWLock 只是省略了任何关于 writer 锁是否是递归的提及递归(reader 端是递归的)。

如果您深入研究一下实现,您会发现 POSIX GRWLock 是使用 pthread_rwlock_twhich needn't be recursive("Results are undefined if the calling thread holds the read-write lock (whether a read or write lock) at the time the call is made.").所以基本上不,GRWLock 不是递归的写锁。

至于如何解决你的问题,我的第一个建议是让 mess_with_datamess_with_data_again 自己获取和释放锁。请记住,您只应在必要时持有锁,而不要再持有锁。

如果出于某种原因这不是一个选项(比如您可能无法访问该代码),您可以使用递归锁,或者将写入器操作限制在一个线程中并使用队列与它。

也可以重构 mess_with_datamess_with_data_again,使它们不需要锁,但这可能会也可能不会,而且可能会非常困难。