簡體   English   中英

在C ++中使用互斥鎖時的奇怪行為

[英]strange behaviour when using mutex in C++

在研究C ++(11)中有關多線程的某些情況時,我遇到了這種奇怪的情況。

我在下面的2個線程中運行increment函數,傳入共享變量的地址。 核心代碼是這樣的:

static std::mutex mtx;

static void increment(int *x, int nofIncrements)
{
    for (int i = 0; i < nofIncrements; i++)
    {
        mtx.lock();
        (*x)++;
        mtx.unlock();
    }
}

如您所見,互斥鎖用於鎖定增量操作(效率低下,我知道正確的解決方案是使用原子操作,但我試圖了解正在發生的事情)。

此代碼在2個線程中運行,其值為nofIncrements = 100000 ,這意味着我希望最終值為200000 但是,有時我得到200001 ,我無法解釋...

完整的類(可在以下要點中找到https://gist.github.com/anonymous/4d218dce2a43a06abe6a ):

class LockedIncrement
{
    int _nofIncrements;
    int _counter;

    static std::mutex mtx;

    static void increment(int *x, int nofIncrements)
    {
        for (int i = 0; i < nofIncrements; i++)
        {
            mtx.lock();
            (*x)++;
            mtx.unlock();
        }
    }

public:

    LockedIncrement(int nofIncrements)
    {
        _nofIncrements = nofIncrements;
    }

    void DoTest()
    {
        std::thread t1(increment, &_counter, _nofIncrements);
        std::thread t2(increment, &_counter, _nofIncrements);
        t1.join();
        t2.join();
        std::cout << "Counter = " << _counter << " (expected " << 2 * _nofIncrements << ")\n";
    }
};

測試可以這樣運行:

int main(int argc, char* argv[])
{
    auto nofIncrements = 1000000;
    std::cout << "locked increment \n\n";
    auto test = LockedIncrement(nofIncrements);
    test.DoTest();
}

要點的代碼增量_counter尚未初始化,這導致行為不確定。 你很幸運得到200000和200001 ...我得到377232 ...

LockedIncrement(int nofIncrements) : 
    _nofIncrements( nofIncrements ), 
    _counter ( 0 )
{
}

暫無
暫無

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

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