线程调用的函数对对象删除安全吗?
Posted
技术标签:
【中文标题】线程调用的函数对对象删除安全吗?【英文标题】:Is function called by thread safe against object delete? 【发布时间】:2018-10-03 09:50:01 【问题描述】:我想知道 thread1 是否通过传递的对象 'obj->fun()' 调用类函数,并且该对象在后台被其他线程删除,例如 thread2 线程 1 的函数执行会发生什么。
例子:
ClassA
int functionA()
...condition(started_execution);
int a=0;
a++;
printf(....a);
return a;
;
void startExecution(void *arg)
/*casting code object A*/
A->functionA();
int main()
ClassA *A = new ClassA();
pthread_create(....,startExecution,(void *)A);
....wait_for(started_execution);
delete A;//just want to know the behaviour and not join method.
问题:在上述场景中,A->functionA 调用函数functionA。如果函数正在执行,那么自对象A调用以来,delete A对函数执行有何影响? functionA 不处理共享数据?
【问题讨论】:
对于初学者,请考虑改用std::thread
。至于你的问题,你想要做的是不好吧,你基本上是在用你的脚射击自己的同时把地毯从你自己的脚下拉出来。这很糟糕。
如果ClassA
有任何functionA
使用的非静态数据成员,或者functionA
是虚拟的,那么你肯定有问题。如果这些都不是真的,你可能没问题,但你也不需要 ClassA
或实例 *A
首先存在
如果你开始投掷手榴弹,手榴弹在你手中爆炸,你能在爆炸后完成投掷吗(假设你没有被爆炸伤害)?
在实践中,由于你使用pthread,我假设你用gcc或clang编译(MSVC空对象ABI处理非常不同),A为空所以functionA
隐含对象参数将不会被访问.因此,您的代码将按您的预期工作。但根据 c++ 标准,这是未定义的行为:对象被销毁后不能调用其成员函数。
我们可以就这里会发生的事情进行有趣的学术辩论(答案几乎可以肯定取决于编译器、月相等)。但是,您应该 永远不要这样做。
【参考方案1】:
如果函数正在执行,那么delete A对对象A调用后的函数执行会有什么影响?
如果执行函数以任何方式使用this
,则影响将是未定义的行为。使用this
是指访问任何数据成员或基本子对象、调用任何成员函数、间接this
或将this
传递给可以执行任何这些操作的函数。
在设置条件变量后,您的 functionA
似乎没有以任何方式使用 this
,因此不会产生任何影响 - 假设条件变量访问本身已正确同步。
但是,这样做并不是一个好主意,因为在functionA
的定义中看不到必须访问任何成员。程序员在以后更改函数时很容易不遵循该要求。
据我所知,这种情况类似于delete this;
的情况,它被认为符合标准,但具有潜在危险:Is delete this allowed?
【讨论】:
是的 - 这是让您烦恼的事情之一,即使它们工作正常。每次在某处发生奇怪的事情时,您都觉得有必要返回并检查类函数是否以某种方式从某处获得了死对象引用,因此开始采取行动。开发已经够困难了,因为它没有可避免的担忧:)以上是关于线程调用的函数对对象删除安全吗?的主要内容,如果未能解决你的问题,请参考以下文章