gpt4 book ai didi

c - pthread_mutex_timedlock 没有超时

转载 作者:可可西里 更新时间:2023-11-01 11:50:30 26 4
gpt4 key购买 nike

操作系统:Linux

库:glibc

我有多个线程访问一个硬件,我通过使用互斥锁来防止争用。

该软件非常复杂,其可能出现的死锁可能是系统中由于递归调用取锁造成的。出于这个原因,我使用“pthread_mutex_timedlock”而不是“pthread_mutex_lock”。我宁愿打印一条错误消息并继续,也不愿让系统看门狗并重置。这将使我能够在不关闭系统的情况下看到问题。

这里有一段代码可以帮助您理解我正在尝试做的事情。

pthread_mutex_t MainMutex = PTHREAD_MUTEX_INITIALIZER;

#define m_TAKE_LOCK() { \
struct timespec abs_time; \
clock_gettime(CLOCK_REALTIME , &abs_time); \
abs_time.tv_sec += 5; \
if (pthread_mutex_timedlock (&MainMutex, &abs_time) != 0) \
{ \
printf("Lock failed PID %d %s\n", getpid(), __func__); \
} \
}

#define m_RELEASE_LOCK() pthread_mutex_unlock(&MainMutex);

void func1(void) {m_TAKE_LOCK()}
void func2(void) {m_TAKE_LOCK()}

void main(void)
{
while (1)
{
func1();
func2();
m_RELEASE_LOCK()
...
}
}

还有其他线程也获取了锁,但这不是问题。我遇到的问题是锁定超时永远不会发生。它会永远等待并监视系统,而这正是我试图避免的。

'abs_time.tv_sec' 是正确的 - 我已经打印了它,并且在我尝试使用它时系统时钟已经初始化。

我知道 Windows 会阻止对同一进程的锁定,但 Linux 没有这种保护。我意识到我不应该递归调用 m_TAKE_LOCK() 但使用 timedlock 的目的是捕获错误(打印消息并继续)。

有人知道我可能做错了什么吗?

最佳答案

您不能尝试获取您已经持有的互斥量。这是不允许的。您假设它会产生一个特定的结果,但不能保证它会这样做。

您应该使用递归互斥体。你应该释放它的次数与你获得它的次数相同。

但是,从根本上说,绝对要求任何获取互斥锁的代码都知道它在运行时持有哪些互斥锁,这些互斥锁与函数可能直接或间接调用的代码相关。 (它不需要知道调用它的代码持有但未被它可能调用的函数触及的“更高级别”互斥锁。)

因此,例如,如果您正在创建一个调用“Bar”的名为“Foo”的类,则“Foo”类的每个函数都必须知道它持有的与“Foo”或“Bar”相关联的任何锁”。如果某个新类,“Qux”调用它,“Foo”代码不需要知道持有什么“Qux”锁,但是如果“Qux”在持有“Bar”锁的同时调用“Foo”,则“Foo”函数必须知道这一点。您必须实现一个健全的锁层次结构。 (除非您完全理解此规则的基本原理并且确定它不适用。)否则,您的代码将永远无法正常工作,除非偶尔运气好。

POSIX spec不要求它超时:“如果不等待另一个线程解锁互斥量就无法锁定互斥量,则在指定的超时到期时应终止此等待。”没有其他线程需要等待。它也不需要错误,“如果出现以下情况,pthread_mutex_timedlock() 函数可能会失败:[EDEADLK] 检测到死锁条件或当前线程已经拥有互斥锁。”“可能”表示错误条件,其支持是可选的,术语“如果发生则失败”用于指示所需的行为。

关于c - pthread_mutex_timedlock 没有超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8541818/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com