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

时间:2019-05-21 13:32:37

标签: c multithreading synchronization thread-safety pthreads

我有两个函数,例如foo()和bar(),我希望它们互斥,即在bar()运行时完全阻止foo()的运行,或者在foo时完全阻止bar()的运行()正在运行以确保线程安全。

但是,我可以在foo()内调用bar(),这是当foo()在foo()内调用bar()时,让bar()运行,但没有其他线程调用bar()。 / p>

有可能吗?如果是,您能提供一般想法吗?

试图在C中使用一个或多个互斥锁,很容易使两个函数互斥,但后来我无法在foo()内调用bar(),它们将进入死锁状态。

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

我正在寻找foo将阻止bar的解决方案,而bar如果在不同的线程中运行,bar将阻止foo。但是当foo在其主体内部调用bar(同一线程)时,让bar运行。

谢谢

2 个答案:

答案 0 :(得分:4)

最简单的方法是将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;
}

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

答案 1 :(得分:0)

另一种方法是使用所谓的“可重入”或“递归”互斥锁/锁定对象。

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

它与常规锁的工作原理完全相同,不同之处在于已锁定线程对next的调用将成功,对lock()的调用将解锁互斥锁,直到线程unlock()解锁次数达到unlock()解锁次数为止。

递归锁是一种功能,它出现在许多不同的多线程库中,但我不了解pthreads库,因此@caf的答案也许对您来说是一个更好的选择。