`boost::shared_mutex`与`boost::upgrade_mutex`之间的区别是什么?

huangapple go评论68阅读模式
英文:

What is the difference in boost::shared_mutex vs boost::upgrade_mutex?

问题

我在想boost::shared_mutexboost::upgrade_mutex之间的区别是什么。我想创建一个多线程应用程序,其中有多个频繁的读取者和一个不太频繁的写入者。

我可以使用标准的shared_mutex以及shared_lockunique_lock。尽管这可能导致写入者饥饿。

我想要的是:
如果一个读取者有一个共享锁,并且有一个写入者正在等待锁,那么其他读取者不会获得访问权限,它们必须等待共享锁。

我几乎找不到关于boost::upgrade_mutex的信息,但我认为这就是我想要的?

我创建了这个示例(请忽略cout发生在锁之外以及我不能控制哪个线程先运行):

#include <iostream>
#include <thread>

#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>

int main()
{
    boost::shared_mutex mutex;

    boost::shared_lock<boost::shared_mutex> read_lock(mutex);

    std::thread t1([&mutex]()
    {
        std::cout << "Thread trying to get the unique lock!" << std::endl;
        boost::unique_lock<boost::shared_mutex> write_lock(mutex);
        std::cout << "Thread got the unique lock!" << std::endl;
    });

    std::thread t2([&mutex]()
    {
        std::cout << "Thread trying to get the shared lock!" << std::endl;
        boost::shared_lock<boost::shared_mutex> read_lock(mutex);
        std::cout << "Thread got the shared lock!" << std::endl;
    });

    // 为了确保线程在解锁之前请求锁
    sleep(1);

    std::cout << "Unlocking first lock" << std::endl;
    read_lock.unlock();

    t1.join();
    t2.join();
}

根据我的测试,如果t1t2之前运行,那么t2在继续之前也会等待read_lock.unlock();。这就是我想要的!

然后,我将boost::upgrade_mutex更改为boost::shared_mutex(在锁的模板参数中也是如此),我看到完全相同的行为。我在文档中找不到这是否有保证或差异是什么。

英文:

I was wondering what the difference is in boost::shared_mutex and boost::upgrade_mutex. I wanted to make a multi threaded application that will have multiple frequent readers and one non frequent writer.

I could just use a standard shared_mutex and a shared_lock and a unique_lock. Although this is likely to give me writer starvation.

What I want is:
If a reader has a shared lock and a writer is waiting on the lock that no other readers will be given access and they will have to wait on the shared lock.

I can find very little information on boost::upgrade_mutex, but I think this is what I want?

I made this example (please ignore that the couts are happening outside of a lock etc and that I can't control which thread runs first):

#include &lt;iostream&gt;
#include &lt;thread&gt;

#include &lt;boost/thread/locks.hpp&gt;
#include &lt;boost/thread/shared_mutex.hpp&gt;

int main()
{
    boost::shared_mutex mutex;

    boost::shared_lock&lt;boost::shared_mutex&gt; read_lock(mutex);

    std::thread t1([&amp;mutex]()
    {
        std::cout &lt;&lt; &quot;Thread trying to get the unique lock!&quot; &lt;&lt; std::endl;
        boost::unique_lock&lt;boost::shared_mutex&gt; write_lock(mutex);
        std::cout &lt;&lt; &quot;Thread got the unique lock!&quot; &lt;&lt; std::endl;
    });

    std::thread t2([&amp;mutex]()
    {
        std::cout &lt;&lt; &quot;Thread trying to get the shared lock!&quot; &lt;&lt; std::endl;
        boost::shared_lock&lt;boost::shared_mutex&gt; read_lock(mutex);
        std::cout &lt;&lt; &quot;Thread got the shared lock!&quot; &lt;&lt; std::endl;
    });

    // To make sure the threads ask for the lock before unlocking
    sleep(1);

    std::cout &lt;&lt; &quot;Unlocking first lock&quot; &lt;&lt; std::endl;
    read_lock.unlock();

    t1.join();
    t2.join();
}

From my testing, if t1 runs before t2, t2 also waits on read_lock.unlock(); before proceeding. This is what I want!

I then changed boost::upgrade_mutex to boost::shared_mutex (in the template param of the locks as well) and I am seeing exactly the same behaviour. I can't find in the documentation if this is guaranteed or what the difference is.

答案1

得分: 1

根据文档,upgrade_mutex 是一个具有额外功能的 shared_mutex,用于支持升级操作。请参考 https://www.boost.org/doc/libs/1_81_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts.upgrade_lockable

UpgradeLockable 概念是 SharedLockable 概念的一个细化,允许拥有可升级所有权以及共享所有权和独占所有权。这是 SharedLockable 概念提供的多读者/单写入模型的扩展:一个线程可以在其他线程具有共享所有权的同时具有可升级所有权。具有可升级所有权的线程可以随时尝试将其升级为独占所有权。如果没有其他线程具有共享所有权,升级将立即完成,线程现在具有独占所有权,必须通过调用 unlock() 来释放,就像通过调用 lock() 一样。

使用 shared_lock 无法将共享锁升级为独占锁而不解锁。upgrade_lock 是共享锁和独占锁之间的一种中间状态。您只能拥有一个升级锁,尽管同时可以获取多个共享锁。您可以请求将升级锁升级为独占锁,但只有在释放所有共享锁后才能成功。 (还可以执行其他操作,但对于理解差异而言它们较不相关)

英文:

Reading the documentation, the upgrade_mutex is a shared_mutex with extra functionality considered upgrading. See https://www.boost.org/doc/libs/1_81_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts.upgrade_lockable

> The UpgradeLockable concept is a refinement of the SharedLockable concept that allows for upgradable ownership as well as shared ownership and exclusive ownership. This is an extension to the multiple-reader / single-write model provided by the SharedLockable concept: a single thread may have upgradable ownership at the same time as others have shared ownership. The thread with upgradable ownership may at any time attempt to upgrade that ownership to exclusive ownership. If no other threads have shared ownership, the upgrade is completed immediately, and the thread now has exclusive ownership, which must be relinquished by a call to unlock(), just as if it had been acquired by a call to lock().

The thing you cannot do with shared_lock is upgrading from shared locking to unique locking, without unlocking. The upgrade_lock is something in-between a shared and a unique lock. You can only have a single upgrade lock, though at the same time multiple shared locks can be taken.
You can ask to upgrade the upgrade lock to a unique lock, which will only succeed after all shared locks are released. (Other operations are also possible, though they are less relevant to understand the difference)

huangapple
  • 本文由 发表于 2023年2月19日 07:45:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75497114.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定