【问题标题】:What happens when object is destroyed when it is stuck in an infinite loop?当对象陷入无限循环时被破坏会发生什么?
【发布时间】:2013-08-07 23:39:02
【问题描述】:

我想知道当对象卡在另一个线程中的无限while循环中时,在对象上调用析构函数会发生什么。

// Main thread creates the object
MyClass _obj = new MyClass():
// doing some stuff
delete _obj;

在哪里,

MyClass::MyClass()
{
 // Start a thread which calls MyClass::MyPollingFn()
}

MyClass:: MyPollingFn()
{
  // runs in new child thread
  while(true)
  {
    // doing some work
    // sleep(5 seconds)
  }
}

说明: MyClass 有一个类对象,它创建一个线程并在无限循环中运行 MyPollingFn 方法。此方法的每次迭代都可以更改一些类变量。可以从持有对象的父线程中销毁对象吗?这有没有可能引起问题?

【问题讨论】:

  • 是的,100% 保证会导致问题
  • 可以吗?如果您想要定义的行为,则不是。在你的线程被终止之前不要销毁它。

标签: c++ linux while-loop destructor infinite-loop


【解决方案1】:

如果MyPollingFn 曾显式或隐式(例如通过访问非静态成员变量)接触this,则此代码将表现出未定义的行为,因为this 将成为悬空指针。

如果它不接触this,那为什么要让它成为一个非静态成员函数呢?

【讨论】:

  • 更准确地说,如果在运行MyPollingFn 的线程中的任何访问没有发生在另一个线程中的delete 之前,程序的行为是不确定的。需要进行一些显式同步以避免数据竞争。
【解决方案2】:

有几个可能的问题,包括
1. 要么你尝试加入你的析构函数中的线程,在这种情况下它会阻塞。


编辑

即如果你添加

MyClass::~MyClass()
{
  myThread.join();
}

MyPollingFunction 保持原样,它永远不会完成,所以join 将阻塞。

结束编辑


虽然这段代码没有析构函数,但也许应该。

2. 否则线程会在类消失后尝试“更改一些类变量”。 这显然很糟糕。
最好改一下

while(true)

while(!finished)

finished 是某种线程安全标志(例如atomic)并将其设置在(当前不存在的)析构函数中。

【讨论】:

  • @Rijin - 根据要求添加了更多详细信息。我怀疑你只需要决定一种方法来告诉你轮询功能停止。
  • 好吧,我觉得我的基础不好。所以让我澄清一下。所以,如果在任何类(obj)上调用析构函数,并且当前正在执行该类中的其他一些方法,两者执行在它自己的调用线程中同时发生,而不关心其他线程,直到其中一个尝试访问一个已经未分配的资源,这将创建一个异常/核心转储......这是正确的吗?
  • @Rijin 简单地说,是的。
猜你喜欢
  • 2015-11-17
  • 2010-11-01
  • 1970-01-01
  • 2019-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 2016-04-08
相关资源
最近更新 更多