【问题标题】:wxWidgets - terminate called without an active exception (using std::thread)wxWidgets - 在没有活动异常的情况下终止调用(使用 std::thread)
【发布时间】:2014-10-14 23:00:34
【问题描述】:

我正在编写 GUI 应用程序,它使用我自己的库,该库基于 boost::asio 一个 C++11 标准库。这是派生自wxAppgui_client 类的gui_client::OnInitgui_client::OnExit 方法的实现:

bool gui_client::OnInit()
{
    io_service_ = new boost::asio::io_service;
    client_ = new client(*io_service_);
    frame = new main_frame();

    std::thread reader([this]() {
        // thread code
    });

    reader_thread = &reader;

    frame->Show();
    Debug("Returning OnInit");
    return true;
}

int gui_client::OnExit()
{
    reader_thread->join();
    return 0;
}

一切都编译完毕,应用程序启动。我在命令行中看到调试信息('Returning OnInit')然后:

在没有活动异常的情况下终止调用

我试图在gdb 的一些wxApp 函数上设置断点,但是我找不到返回错误的地方。 gui_client 类只有三个方法:

  • virtual bool OnInit()
  • virtual int OnExit()
  • client * get_client()

当我不启动阅读器线程 (std::thread reader) 时,一切正常。当我在 lambda 函数中使用空循环启动线程时,我得到了上面提到的错误。我也确信线程代码是正确的,因为相同的代码在 CLI 测试应用程序中运行良好。

我使用wxWidgets 3.0.1.0g++ 4.7.2 (Debian)。我使用这个 g++ 命令进行编译:

g++ `wx-config --version=3.0 --cxxflags` -std=c++11 -I./headers -I../headers -L../lib/Debug -DDEBUG -g -c -o [obj_file] [source]

这个链接命令:

g++ `wx-config --version=3.0 --cxxflags` -std=c++11 -I./headers -I../headers -L../lib/Debug -DDEBUG -g [obj_files] -ltamandua `wx-config --version=3.0 --libs` -lboost_system -pthread -o [output]

【问题讨论】:

    标签: c++ multithreading c++11 wxwidgets


    【解决方案1】:

    问题就在这里:

    std::thread reader([this]() {
        // thread code
    });
    
    reader_thread = &reader;
    

    reader 将在OnInit 函数结束后被销毁(并且终止将被调用,因为thread 是可连接的)。在这种情况下,您应该在类中使用智能指针,或者使用new 创建reader_thread,或者只是将线程保存在对象中并通过移动将其分配给您的reader_thread(reader_thread 应该是对象,而不是指针)。

    1) reader_thread = std::make_shared<std::thread>([this]() {});

    2)reader_thread = new std::thread([this]() {});

    3)

    std::thread reader([this](){});
    reader_thread = std::move(reader);
    

    【讨论】:

    • @Griwes 它也会被移动。只是没有命名变量reader,但将调用移动赋值运算符。
    • 感谢您的帮助!多么愚蠢的错误......和简单的解决方案。
    • @ForEveR,当然。然而,我的方式是一种非临时性的,并且缩短了一行,它的作用立即显而易见(而你的方法需要更多的时间才能得到它的作用)。
    猜你喜欢
    • 2020-03-06
    • 1970-01-01
    • 2011-09-09
    • 2016-10-07
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 2021-10-10
    • 1970-01-01
    相关资源
    最近更新 更多