为什么互斥锁不能与2个共享资源的线程一起使用?

问题描述 投票:1回答:1

我想测试一种情况,在该情况下,我检查weak_ptr的有效性并返回shared_ptr。在检查和返回其他线程是否删除了shared_ptr之间,我们将面临异常。我尝试使用Windows sleep或cout模拟相同的场景,但似乎无法正常工作。代码如下:

#include <iostream>
#include <thread>
#include <windows.h>
#include <mutex>

using namespace std;

mutex m;

struct Block
{
    int * p_ = nullptr;
    Block() { p_ = new int[10000]; refCount_++; }


    ~Block() { delete[] p_; _p = nullptr; }

    int refCount_;
};

struct Weak_ptr
{
    Block * p_ = nullptr;
    Weak_ptr() { p_ = new Block(); }
    void Addref() { p_->refCount_++; }
    void release() { delete[] p_; p_ = nullptr; cout << "\nptr deleted\n"; }
};

void funct1(int x, Weak_ptr *ptr)
{
    cout << "\nin thread 1 \n";
    cout << "\nSleep thread 1\n";
    //Sleep(x)
    for (int i = 0; i < x; i++)
        cout << ".";
    cout << "\nAwake thread 1\n";
    ptr->release();
}

void funct2(int x, Weak_ptr *ptr)
{
    m.lock();
    cout << "\nin thread 2 \n";
    if (ptr->p_)
    {
        cout << "\nptr checked \n";
        //Sleep(x)
        for (int i = 0; i < x; i++)
            cout << "|";

        cout << "\nusing ptr in t2\n";
        ptr->Addref();
    }
    else
    {
        cout << "\ncheck succeeded \n";
    }
    m.unlock();
}

int main()
{
    Weak_ptr s;
    thread t1(&funct1, 2000, &s);
    thread t2(&funct2, 4000, &s);
    t1.join();
    t2.join();
}
c++ multithreading mutex stdthread
1个回答
0
投票

无论您在哪里更改共享数据,都必须保护代码。

让我举例说明您的情况:

m.lock(); // what does that mean?
// do your business

您的互斥锁m是WC门。如果有人已经从另一侧锁定,那么您将无法进入。因此,当按下m.lock()时,会发生两件事。

  1. 检查是否有人已经在锁着的门后面
  2. 通过并锁好门

现在想象另一种导致相同WC但没有锁定的方法。只是一扇没有安全的门。

// No m.lock() here

无论另一扇门是否被锁定都没有关系,任何人都可以随时加入厕所(不酷)。

现在想象第三种情况。

m2.lock();
// Do other stuff

现在您有了另一扇门,但是还有另一把锁。这样两个人可以同时进入门。用代码类比,如果静音引用不同,则代码不安全。

© www.soinside.com 2019 - 2024. All rights reserved.