簡體   English   中英

刪除被鎖定的互斥鎖

[英]Deleting a mutex that is locked

我有一個包含多個資源的程序,需要由它們自己的互斥鎖鎖定。

在這個程序中,可能會發生在資源 A 的互斥鎖被鎖定時,資源 A在另一個線程中被刪除。

以下代碼嘗試重現我嘗試完成的邏輯:

#include <thread>
#include <mutex>
#include <iostream>
#include <map>
int g_i = 0;
struct Resource
{
    std::mutex* m_mutex;
};

std::map<unsigned int, Resource> myResources;

std::mutex g_i_mutex;  // protects g_i

void shutdown()
{
    std::cout << "shutdown -> myMap.size = : " << myResources.size() << std::endl;
    std::lock_guard<std::mutex> lock(*myResources[1].m_mutex);
    ++g_i;
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    delete myResources[1].m_mutex;
    myResources[1].m_mutex = NULL;
    myResources.erase(1);
    std::cout << "shutdown -> myMap.size = : " << myResources.size() << std::endl;
    std::cout << "shutdown : " << g_i << '\n';


}

 void onRecognize()
{
    std::cout << "onRecognize -> myMap.size = : " << myResources.size() << std::endl;
    std::lock_guard<std::mutex> lock(*myResources[1].m_mutex);
    std::cout << "onRecognize -> myMap.size = : " << myResources.size() << std::endl;
    ++g_i;

    std::cout <<  "onRecognize : " << g_i << '\n';


}

int main()
{
    std::cout << __func__ << ": " << g_i << '\n';
    Resource myStruct;
    myStruct.m_mutex = new std::mutex();
    myResources[1] = myStruct;
    std::thread t1(shutdown);
    std::thread t2(onRecognize);

    t1.join();
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    t2.join();

    std::cout << __func__ << ": " << g_i << '\n';
}

我試過這段代碼,它的工作原理。 但我想知道onRecognize函數中的lock_guard會發生什么,因為互斥鎖在他被鎖定時被刪除。 所以,我的問題可能是:

當他被鎖定在其他地方時刪除互斥鎖是否危險?

謝謝

不要在鎖定時銷毀互斥鎖​​。

如果互斥鎖由任何線程擁有,或者任何線程在持有互斥鎖的任何所有權時終止,則行為未定義。

http://en.cppreference.com/w/cpp/thread/mutex/~mutex

您有一個基本的並發錯誤,導致您的代碼不可靠。 指針m_mutex在一個線程中被修改並在另一個線程中使用,並且沒有任何類型的同步來保護它。

即使您無法想象它會失敗的方式,這也是災難性的。 但碰巧很容易想象它可能失敗的方式。 考慮:

  1. onRecognize評估*myResources[1].m_mutex但尚未構建鎖保護。
  2. shutdown獲取鎖,銷毀互斥鎖​​,然后返回。
  3. onRecognize嘗試在不再存在的鎖上構造鎖保護。
  4. 繁榮。

因此,您遇到的問題比任何特定於互斥體語義的問題都大。

GCC(10.2) 和 Clang(10) 沒有刪除鎖定互斥鎖的問題,MSVC 19.28 將終止。

{
    std::mutex m;
    m.lock();
}//std::terminate() - MSVC

暫無
暫無

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

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