中断信号破坏类对象

时间:2018-12-01 03:47:50

标签: c++ c++11

我正在开发c ++应用程序,并且在使用c ++ 11时遇到信号处理问题。 我想在SIGINT信号到达时在我的主应用程序下创建的所有对象(在堆栈以及堆上创建的)调用析构函数。

请在此处建议复杂的解决方案。 适合您的时间。

感谢和问候, 欧雅斯

3 个答案:

答案 0 :(得分:1)

另一种解决方案是使用shared_ptr。 “共享对象”将在程序结束时自行毁灭!只需确保正确捕获SIGINT并正常退出()。

#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <iostream>
#include <memory>
class Crap {
    public:
    Crap() {};
    ~Crap() {printf("destructor called\n");} 
};
int main(void)
{
    std::shared_ptr<Crap> cc = std::make_shared<Crap>();
    return 0;
}

输出:

ass@xxx:/tmp$ ./a.out 
destructor called

完整示例

#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <iostream>
#include <memory>
#include <csignal>

using namespace std;

class Crap {
    public:
    Crap() {};
    ~Crap() {printf("destructor called\n");} 
};

static volatile sig_atomic_t got_signal = 0;
void signalHandler( int signum ) {
     // AVOID REENTRANCY !!!!
     got_signal = 1;
}
int main(void)
{
    std::shared_ptr<Crap> cc = std::make_shared<Crap>();
    signal(SIGINT, signalHandler);  

    while(1) {
        cout << "PLEASE GIVE ME A SIGINT SIGNAL" << endl;
        if(got_signal == 1){
            break;
        }
        sleep(1);
    }
    return 0;
}

答案 1 :(得分:0)

堆对象的示例-根据您的需要完成它!运行它并通过按CTRL + C为其发出SIGINT信号:

QTabBar::scroller { /* the width of the scroll buttons */
    width: 40px;
}

QTabBar QToolButton { /* the scroll buttons are tool buttons */
    width: 15px;
    border-width: 2px;
}

答案 2 :(得分:0)

如果您的程序编写良好,则几乎不需要执行任何操作来确保调用所有析构函数。这是一种方法。

  1. 当要调用所有析构函数时,引发异常。这将从stack unwinding开始。
  2. main函数中捕获异常。此时,除了main函数本身中声明的变量(可能是某些变量)之外,堆栈展开已使用自动storage duration为每个变量调用了析构函数。
  3. 通过return函数执行main。这将为具有自动存储持续时间的其余变量调用析构函数。然后将调用std::exit,该调用将调用具有线程本地或静态存储持续时间的所有对象的析构函数。

这将明确覆盖除具有动态存储持续时间的对象以外的所有对象。但是,它隐式地涵盖了那些动态对象,因为我以编写良好程序的条件来对此进行了限定。对我而言,编写良好的程序应使用RAII来清理动态内存,因为清理了非动态变量。

如果您不使用RAII,则很可能会头疼。