我正在开发一个多线程演示应用程序,以测试我公司的一些程序分析工具。
我生成两个线程并有一个互斥锁来控制对一堆对象的访问。
我相信top()
函数正在返回引用而不是我的对象的副本到我的线程...随后当我在访问堆栈后释放互斥锁时,另一个线程抓取互斥锁。奇怪的事发生了。
A
std::stack<polygon> * polygonList = new std::stack<polygon>();
threadedFuntion()
{
polygon p = polygonList->top();
polygonList->pop();
ReleaseMutex(polyListMutex);
// preform point in polygon check
bool done = false;
while(!done)
{
done = p.doWork();
}
}
该程序的结构如下
乙
std::stack<polygon> * polygonList = new std::stack<polygon>();
threadedFuntion()
{
// preform point in polygon check
bool done = false;
while(!done)
{
done = polygonList->top().doWork();
}
polygonList->pop();
ReleaseMutex(polyListMutex);
}
但是,在完成其工作之前,它不会释放互斥锁。
我希望线程获取多边形对象的副本,将其从堆栈中取出,然后释放互斥锁,然后继续执行其工作。
编辑我正在关注互联网和线程的this指南
编辑覆盖operator =
polygon& polygon::operator=(const polygon &obj)
{
if (this == &obj)
return *this;
std::cout << "equals";
pa = obj.pa;
return *this;
}
答案 0 :(得分:0)
当您使用top()
时,您将获得对polygonList上的对象的引用。当您使用pop()
时,您将从polygonList中删除相同的元素,该元素在流程中调用该元素析构函数,并且对该对象的任何引用都不再有效。
在您的代码中,您似乎正在创建一个对象多边形,并将其设置为等于从堆栈顶部返回的引用。我确保多边形有一个正确执行深层复制的复制构造函数(如果需要)。
当你调试它时,你从堆栈中弹出顶部元素后,多边形p的成员变量会发生什么?这应该可以让你深入了解正在发生的事情。
另一件需要考虑的事情是,&#34;糟糕的例子&#34;你可以在&#34;做工作&#34;你的代码部分。您的代码部分是否是线程安全的?该代码是否正在访问其他可能导致问题的线程中常见的数组或对象?
答案 1 :(得分:0)
你还没有给出足够的信息,但我会假设polygon::pa
是指向一系列点的某种指针,或者更糟糕的是,指向std :: vector的指针或者其他一些。在赋值运算符(可能是你的拷贝构造函数)中,你只是复制指针,这样当在这一行调用拷贝构造函数时:
polygon p = polygonList->top();
... p
与polygonList中的顶部元素具有相同的指针。
当您再调用polygonList->pop()
时,polygonList
中的顶部多边形将被销毁,这可能会调用delete [] pa
。因此,p
现在将有一个指向已删除内存的指针。
您应确保了解rule of three及其现代版本rule of five and rule of zero。一旦你理解了这些,考虑将pa
作为点向量(不是指向点向量的指针),或者如果你坚持采用更加手动的方法,至少使用std :: unique_ptr
此外,在您的示例中,没有理由使用std::stack<polygon> * polygonList = new std::stack<polygon>();
只说std::stack<polygon> polygonList;
。它更短,更清晰,更正确。看起来你正在尝试用C ++编写Java或C#。学会喜欢堆栈和自动资源管理,而不是手动的资源管理方法。