C++ 为什么互斥不能与共享资源的两个线程一起工作?

C++ 为什么互斥不能与共享资源的两个线程一起工作?,c++,multithreading,mutex,stdthread,C++,Multithreading,Mutex,Stdthread,我想测试一个场景,在这个场景中,我检查弱\u ptr的有效性并返回共享\u ptr。在检查和返回其他线程是否删除了共享的\u ptr之间,我们将面临异常。我尝试使用windows sleep或cout模拟相同的场景,但似乎不起作用。代码如下: #include <iostream> #include <thread> #include <windows.h> #include <mutex> using namespace std; mutex

我想测试一个场景,在这个场景中,我检查弱\u ptr的有效性并返回共享\u ptr。在检查和返回其他线程是否删除了共享的\u 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();
}
#包括
#包括
#包括
#包括
使用名称空间std;
互斥m;
结构块
{
int*p_uu=nullptr;
Block(){p_979;=new int[10000];refCount_979;++}
~Block(){delete[]p_u;u p=nullptr;}
int refCount;
};
结构弱ptr
{
Block*p_u2;=nullptr;
弱_ptr(){p_u=new Block();}
void Addref()

void release(){delete[]p_;;p_uu=nullptr;cout无论在何处更改共享数据,都必须保护代码

让我用一个例子来解释你的情况:

m.lock(); // what does that mean?
// do your business
你的互斥锁m是一个厕所门。如果有人已经从另一边锁上了,那么你就不能进去。所以当按下
m.lock()
时,会发生两件事

  • 检查是否有人已经在锁着的门后面
  • 穿过去锁上门
  • 现在想象一下,另一条路通向同一个厕所,但没有锁,只有一扇没有安全的门

    // No m.lock() here
    
    不管另一扇门是否上锁,任何人都可以随时加入WC(不酷)

    现在想象第三种情况

    m2.lock();
    // Do other stuff
    

    现在你有了另一扇门,但有了另一把锁。因此两个人可以同时访问这扇门。在代码类比中,如果静音引用不相同,那么代码就不安全。

    互斥锁不是单方面交易。所有访问资源的线程都需要使用同一个互斥锁。这是一种合作。Bug#1:the
    refCount
    当构造函数完成时,块上的成员有一个未定义的值。您需要显式地将
    refCount
    初始化为
    1
    ,而不是增加一个未定义的值。您可以发布程序的输出吗?它会引发异常吗?Bug#2:
    Weak#ptr::release
    只是盲目地删除基础对象regardless
    refCount\uu
    成员的值。我希望它减少refCount,然后在它变为零时删除。有两个智能指针模板
    std::shared_ptr
    std::weak_ptr
    ,它们似乎正是您试图实现的目标。为什么不使用它们?即使不使用,您也可以查看它们r实现,以了解它们如何解决您的问题。