可杀死线程类中的编译错误

Posted

技术标签:

【中文标题】可杀死线程类中的编译错误【英文标题】:compilation error in killable thread class 【发布时间】:2018-04-14 11:54:54 【问题描述】:

我正在尝试设计一个派生自 std::thread 的 killable_thread 类。

该类应该有一个名为 die() 的成员,可以调用该成员来终止线程。

我的first attempt忽略了资源泄露的问题。它只是尝试调用析构函数,但没有编译:

/** killable_thread

    A class that inherits the thread class to provide a kill() operation.
    version 1.0 : only kills the thread. Ignores resources.

**/

#ifndef KILLABLE_THREAD
#define KILLABLE_THREAD

#include <thread>       /// thread
#include <iostream>     /// cout, endl


struct killable_thread : std::thread

   /// inherit the thread class' constructor
   /// [CPL], $20.3.5.1
   using std::thread::thread;
   using std::thread::operator=;

   ~killable_thread()
   
   

   void die()
   
      ~killable_thread();
   
;


void f();


int main()

   killable_thread kt f;

   kt.die();

   std::cout << "OK" << std::endl;



void f()



#endif  ///  KILLABLE_THREAD

编译错误为:

main.cpp: In member function 'void killable_thread::die()':
main.cpp:28:7: error: no match for 'operator~' (operand type is 'killable_thread')

       ~killable_thread();
       ^~~~~~~~~~~~~~~~~~

我应该怎么做?

【问题讨论】:

从其成员函数中调用对象的析构函数是有风险的 - 为什么需要这样做? 好吧,我还能如何终止线程? 你不能。在 C++ 中杀死线程的唯一类型安全是线程抛出异常以展开其所有范围,并从原始线程函数返回。此外,这与调用某个对象的析构函数完全无关。 std::thread 只是一个对象。在这方面与std::cout 没有什么不同。唯一不同的是它有一个执行线程链接到它。并且指定如果在线程仍在运行时销毁它,整个程序将中止。线程不能以这种方式工作。 this-&gt;~killable_thread();(*this).~killable_thread(); 会帮助编译器。 是的。但是“终止”并不意味着“调用你自己的析构函数”。这意味着从原始线程函数返回。正如我所写,执行线程和std::thread 对象并不相同。事实上,一个线程不可能调用它自己的析构函数。如果可连接线程在其std::thread 析构函数被调用时仍在运行,则整个程序终止;并且线程仍然必须运行才能调用其析构函数。并在其执行线程被分离后调用std::thread 的析构函数,完全没有完成任何事情。 【参考方案1】:
~killable_thread();

编译器将其解释为 将一元 operator~ 应用于使用默认构造函数 killable_thread() 创建的临时对象。要像方法一样调用析构函数,您应该像下面这样调用它:

this->~killable_thread();

(*this).~killable_thread();

【讨论】:

【参考方案2】:

您可能需要添加“this”关键字:

this->~killable_thread();

还有一种写法:

delete this;

但是如上所述,不建议在方法中调用析构函数

【讨论】:

delete this 也有未定义的行为,除非当前对象 (*this) 是使用运算符 new 创建的

以上是关于可杀死线程类中的编译错误的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式从风暴螺栓中杀死拓扑时编译错误:对象和包具有相同的名称

另一个类中的方法“不存在”编译器错误[重复]

错误编译进程 SIGALRM kill

在类中使用自定义排序时出现编译错误 [重复]

创建线程时出现编译时错误

gcc 编译错误:模板类表中嵌套类 A ​​的成员在嵌套朋友类中不可见。为啥?