什么是while(pthread_mutex_trylock(mutex))

时间:2014-01-17 06:16:21

标签: c linux pthreads memcached

我最近在文件memcached.h中阅读了memcached的源代码。我找到了这段代码:

static inline int mutex_lock(pthread_mutex_t *mutex)
{
    while (pthread_mutex_trylock(mutex));
    return 0;
}

我只是想知道为什么不直接使用pthread_mutex_lock。上述代码有什么优势?

sleep 1 or 2 seconds看起来更合理之后

pthread_mutex_trylock,因为它不会浪费CPU资源。

有什么想法吗?

感谢。

2 个答案:

答案 0 :(得分:1)

这本质上是一个自旋锁。我们的想法是让线程避免在内核中阻塞,这可能会损害线程的效率。

这种自旋锁只有在锁具有相当低的争用率和/或被保持很短的时间内才有意义。显然,如果你在while循环中进行一系列迭代,那也会导致效率下降。

另外,我相信libc通常会在阻塞之前通过一点点旋转来实现pthread_mutex_lock(),但是我必须深入研究(可能很难阅读)来源来验证它。

另一点 - 在单核系统上运行这将是非常愚蠢的代码,但这些代码正在灭绝。

答案 1 :(得分:0)

这样你就可以让另一个函数等待资源被解锁。这也是pthread_mutex_lock的作用。但是,try_lock可用于防止死锁条件,如优先级反转情况。由于该函数返回错误而不是阻塞进程(如pthread_mutex_lock那样)。

但我同意这基本上实现了pthread_mutex_lock,不同之处在于您可以扩展此自定义函数以防止死锁。

编辑: 如果您添加几秒钟的睡眠,可能会再次声明资源,因为几秒钟是相对较长的时间。通过不添加睡眠,您可以在可能的情况下强制锁定资源,因此与等待相比更加公平。

假设我们有3个线程B,C,D正在等待A锁定的同一资源 假设我们分别有1秒的睡眠和B,C,D的到达时间。 0.1, 0.15, 0.2 所有三个线程都需要0.25秒的资源(为简单起见),A需要0.1秒。 然后,如果每个线程每秒都需要资源,那么我们可能会遇到这种情况 A 1.0 {}发布资源,然后资源B可以在1.1声明它并在0.35发布,其他任何线程都无法声明它,因为它们正等着这​​个时刻。然后,资源A在时间1.9获得收益并再次声明资源并在2.0处释放它。之后B时,线程2.1再次声明它。这可确保只有资源AB才能声明资源。因此,我们会遇到线程CD的饥饿。

当然这是糟糕的设计,但是你应该在编写函数时使用它来锁定资源。但是,使用随机睡眠将解决此问题,但您需要再次了解有关资源使用的知识。