如果 bar() 和 foo() 互斥,如何在 foo() 中 运行 bar()

How to run bar() inside foo() if bar() and foo() are mutually exclusive

我有两个函数,比如 foo() 和 bar(),我希望它们互斥,即当 bar() 为 运行 时完全阻止 foo() 的 运行ning为了线程安全,当 foo() 运行ning 时完全 ning 或阻塞 bar() 的 运行ning。

但是,我可能会在 foo() 中调用 bar(),也就是说,当 foo() 在 foo() 中调用 bar() 时,让 bar() 到 运行,而不是任何其他线程调用 bar().

可能吗?如果是,请问您能提供大概的思路吗?

尝试在C中使用一个或多个互斥量,很容易使两个函数互斥,但我无法在foo()中调用bar(),它们会陷入死锁。

我不能在 foo() 中调用 bar() 之前就解锁互斥量,因为我不能保证下一个 bar() 运行ning 是在 foo() 中调用的那个。

我正在寻找 foo 会阻塞 bar 的解决方案,如果它们 运行 在不同的线程中,bar 也会阻塞 foo。但是当 foo 在它的体内(同一个线程)调用 bar 时,让 bar 运行.

谢谢

最简单的方法是将 bar()foo() 的主要实现移动到单独的辅助函数 bar_unlocked()foo_unlocked(),然后实现 bar()foo() 作为:

type foo(args)
{
    type result;

    pthread_mutex_lock(&barfoo_lock);
    result = foo_unlocked(args);
    pthread_mutex_unlock(&barfoo_lock);

    return result;
}

type bar(args)
{
    type result;

    pthread_mutex_lock(&barfoo_lock);
    result = bar_unlocked(args);
    pthread_mutex_unlock(&barfoo_lock);

    return result;
}

您可以从 foo_unlocked() 的实现中安全地调用 bar_unlocked()

另一种方法是使用 so-called "reentrant" 或 "recursive" mutex/lock 对象。

https://en.cppreference.com/w/cpp/thread/recursive_mutex

它的工作原理与普通锁完全相同,除了从已经锁定它的线程调用 lock() 会成功,而调用 unlock()解锁互斥锁,直到线程unlock()打开锁的次数与它lock()打开锁的次数一样多。

递归锁是一个出现在许多不同multi-threading库中的特性,但我不知道pthreads库,所以@caf的回答可能对你来说是更好的选择。