首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pthread_mutex_timedlock未超时

pthread_mutex_timedlock未超时
EN

Stack Overflow用户
提问于 2011-12-17 08:52:33
回答 2查看 7K关注 0票数 3

操作系统: Linux

lib: glibc

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

软件非常复杂,其可能的死锁可能存在于系统中,原因是递归调用获取锁。由于这个原因,我使用'pthread_mutex_timedlock‘而不是’pthread_lock‘。我宁愿打印一条错误消息并继续,也不愿导致系统监视并重置。这将允许我在不关闭系统的情况下看到问题。

这里有一些代码片段,可以帮助你理解我想要做的事情。

代码语言:javascript
复制
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(),但是使用时间锁的目的是捕获but (打印一条消息并继续)。

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

EN

回答 2

Stack Overflow用户

发布于 2011-12-17 09:08:14

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

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

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

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

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

票数 4
EN

Stack Overflow用户

发布于 2011-12-17 09:10:54

您的代码在我的linux机器上运行良好:

代码语言:javascript
复制
nils@doofnase:~$ gcc test.c -o test -lpthread -lrt
nils@doofnase:~$ ./test
Lock failed PID 2333 func2
Lock failed PID 2333 func2
Lock failed PID 2333 func2
Lock failed PID 2333 func2
^C

这是我所期望的输出。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8541818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档