【发布时间】:2020-04-29 20:27:08
【问题描述】:
我想测试一个场景,我检查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();
}
【问题讨论】:
-
互斥锁不是单方面的交易。访问资源的所有线程都需要使用相同的互斥锁。这是一个合作的事情。
-
错误 #1:当构造函数完成时,Block 上的
refCount_成员具有未定义的值。您需要将refCount显式初始化为1,而不是增加未定义的值。 -
你能发布你的程序的输出吗?它会触发异常吗?
-
错误 #2:
Weak_ptr::release只是盲目地删除底层对象,而不管refCount_成员的值如何。我希望它会减少 refCount,然后如果它变为零则删除。 -
有两个智能指针模板
std::shared_ptr和std::weak_ptr似乎完全符合您的目标。你为什么不用那些?即使没有,您也可以查看他们的实现,了解他们如何解决您的问题。
标签: c++ multithreading mutex stdthread