在pthread_mutex_unlock()上获取errno EAGAIN

时间:2015-05-06 10:18:49

标签: c++ visual-c++ pthreads mutex

我在SAP代理日志中收到以下错误,

(5538F3C3.0122-3154:pthread_mutex_unlock.c,44,"pthread_mutex_unlock") errno EAGAIN

此代理人进入无反应状态后。 这是pthread_mutex_unlock()返回错误代码EAGAIN的正确行为吗? 如果是这样,任何人都可以帮助我在这种情况下获得错误处理的洞察力。

2 个答案:

答案 0 :(得分:1)

是的,Single UNIX Specification,至少到问题6,指出pthread_mutex_unlock可以返回EAGAIN,如果"无法获取互斥锁,因为互斥锁的最大递归锁数已经已超出"。

现在这可能没有多大意义,因为你试图发布互斥锁而不是获取它,但是,因为它在文档中(并且从那以后)至少SUSv2),你可能应该允许它。 SUS的问题7不再将EAGAIN列为pthread_mutex_unlock的可能错误,但是,由于您正在获取它,这可能不是您的实施符合的问题。

如何处理它的问题是一个有趣的问题。 EAGAIN是您通常用于非阻塞I / O操作的代码,您应该稍后再尝试。但无论原因如何,从pthread_mutex_unlock返回错误可能意味着互斥锁已解锁。

因此,如果您再次尝试,那么当您认为自己已将其释放时,这可能会导致互斥锁被锁定,从而导致您以后无法做出反应。你试图再次锁定它。

您可能想尝试几次(可能在重试之间的时间增加)然后退出。这可能需要对您的应用程序进行一些重新设计,这样您就不会丢失数据。

您还应注意线程正在尝试解锁未实际锁定的互斥锁的情况。与上述链接的SUS文档指出,在某些情况下,解锁由另一个线程锁定或未锁定的互斥锁是未定义的行为。在其他一些情况下,保证会为此返回错误。这一切都取决于互斥锁类型(正常,错误检查,递归或默认)。

最后,请确保您从正确的位置获得错误。您的日志消息中包含单词errno,但您需要清楚该函数中的错误代码是返回,而不是存储在实际的errno变量中。

答案 1 :(得分:1)

总的来说,EAGAIN是鼓励你稍后重试你的电话,而实际上却无法实现它。

您确定在锁定的互斥锁上调用了unlock吗?因为解锁未锁定的互斥锁会导致未定义的行为。仔细阅读本手册,根据互斥锁类型有不同的行为。