C 互斥锁已经被我锁定了吗?

C 互斥锁已经被我锁定了吗?,c,mutex,C,Mutex,函数在变量上执行操作,这些变量必须通过互斥来防止并发线程。 此函数的调用方锁定互斥锁,执行其他操作并调用此函数 现在出现了一种情况,需要从另一段代码调用此函数。 当然,这段代码也可以锁定互斥体,但我想也许函数可以看到它是否必须锁定互斥体 我需要的是一个函数,它告诉我当前线程是否锁定了互斥锁。然后,该功能可以在不锁定的情况下继续运行。否则它会锁上 int need_to_lock = !my_thread_has_locked_the_mutex(&mutex); if (need_to

函数在变量上执行操作,这些变量必须通过互斥来防止并发线程。
此函数的调用方锁定互斥锁,执行其他操作并调用此函数

现在出现了一种情况,需要从另一段代码调用此函数。
当然,这段代码也可以锁定互斥体,但我想也许函数可以看到它是否必须锁定互斥体

我需要的是一个函数,它告诉我当前线程是否锁定了互斥锁。然后,该功能可以在不锁定的情况下继续运行。否则它会锁上

int need_to_lock = !my_thread_has_locked_the_mutex(&mutex);

if (need_to_lock)
    mutex_lock(&mutex);

access variables;

if (need_to_lock)
    mutex_unlock(&mutex);
我的线程是否已锁定互斥锁?我什么也找不到

编辑评论 我不知道递归互斥体。他们似乎做了我想做的事。

我现在使用的是一个非递归互斥锁,如果从同一个线程锁定两次,它就会阻塞。

为什么不直接使用递归互斥锁呢?递归互斥体基本上类似于常规互斥体,但可以由单个线程多次锁定(即递归锁定)

在某些库中,默认情况下互斥体是递归的。对于C pthread,您需要通过适当地初始化互斥锁来选择使用递归互斥锁:

pthread\u mutexttr\u attr;
pthread_mutexattr_init(&attr);
pthread_mutextatr_settype(&attr,pthread_MUTEX_RECURSIVE);
pthread_mutex_init(mutex和attr);

另一种方法是将函数分为两种变体:一种应在保持互斥的情况下调用,另一种应在不保持互斥的情况下调用。通常的命名约定是将
\u locked
附加到前者,或将
\u unlocked
附加到后者。unlocked函数只是锁定互斥锁,然后调用locked函数,因此这里不会有任何真正的代码重复

如果您在同一个线程中,那么可以使用一个锁,再次锁定没有什么害处(请参阅:“递归互斥”)。如果另一个线程已锁定,那么您的线程将等待锁定,这正是互斥锁的点。您提出的检查然后执行操作的情况是正在形成的竞争条件,因为另一个线程可能会在检查和操作之间锁定/解锁。。。。这种通用的习惯用法非常常见:在处理跨线程依赖关系之前,不需要检查,只需尝试(使用支持此功能的API),然后检查是否有效。当然,细节各不相同,包括尝试是否会阻塞,但一般模式适用于几乎所有的同步操作和许多原子操作。实际上,这甚至是单线程代码的标准习惯用法:看看有多少函数的返回值传递信息,包括函数是否成功。“因为另一个线程可以在检查和操作之间锁定/解锁”-是的,另一个线程可以在这一刻锁定,但这不会有什么坏处,因为我的函数会按照互斥体的预期等待。唯一的一点是,如果我的线程已经有了互斥锁,那么我就不必再锁定它了。