簡體   English   中英

許多鎖在同一個互斥鎖上,一個永遠鎖定

[英]many locks on same mutex, one locks forever

在我的程序中,我有一個互斥鎖和兩個線程。 其中一個線程經常獲得鎖定。 另一個線程試圖獲得但必須永遠等待。

可能是因為鎖定在釋放之后獲得如此之快,以至於另一個線程沒有機會? 互斥體總是給每個人一個機會嗎? 如果沒有,什么是一個好的解決方案?(某種FIFO鎖?)

我正在使用std :: mutex和std :: lock_guard

問題擴展 seccpur指出std :: condition_variable將是這個問題的解決方案。 這如何與三個線程一起擴展? std :: condition_variable是否確保每個線程都轉向? 假設您使用notify_one()。

std :: mutex不保證給每個人一個平等的機會。 因此,一個線程可能會使另一個線程挨餓。 你可以嘗試的第一件事是插入std :: this_thread :: yield()並查看它是否有幫助。 如果這沒有幫助,那么您的代碼必須具有邏輯錯誤。 發布部分代碼,我們可以幫助您進一步診斷。

使用seccpur的提示我提出了以下解決方案,以防止挨餓單個線程。

#include <condition_variable>
#include <mutex>
#include <atomic>

class NoStarveLock
{
    std::condition_variable condition;
    std::atomic_flag flag = ATOMIC_FLAG_INIT;
    std::mutex conditionLock;
public:
    void lock()
    {
        std::unique_lock<std::mutex> lck(conditionLock);
        while (flag.test_and_set()) // multiple threads can wake up at the same time, so use a set+test
        {
            condition.wait(lck); // wait for a wakeup
        }
    }

    void unlock()
    {
        std::unique_lock<std::mutex> lck(conditionLock);
        flag.clear();
        condition.notify_all();
    }
};

使用std::mutexstd::lock_guardstd::unique_lock (reader)和std::condition_variable std::unique_lock _mutexLockCondition,_mutexObject和_dataContainer在ReaderClass和WriterClass之間共享。

試圖在實際的數據容器上有點模糊,所以getDataContainer()addDataToContainer()取決於你。

std::shared_ptr< Data > ReaderClass::read()
{
    std::unique_lock< std::mutex > lock( _mutexObject );

    // handle spurious wakeup from waitForMessageNotification
    while( _dataContainer.empty() )
    {
        if( waitForMessageNotification( lock ) )
        {
            // timeout occurred, return nullptr to prevent blocking
            return nullptr;
        }
    }

    return getDataFromContainer();
}

bool ReaderClass::waitForNotification( unique_lock< mutex > & lock )
{
    //_mutexLockCondition is a std::condition_variable
    return _mutexLockCondition.wait_for( lock, std::chrono::milliseconds( 100 ) )
                                            == std::cv_status::timeout;
}


void WriterClass::write( std::shared_ptr< Data > dataPtr )
{
    std::lock_guard< mutex > lock( _mutexObject );

    addDataToContainer( dataPtr );

    _mutexLockCondition.notify_one();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM