使用静态链接启动std::线程会导致分段错误

Starting a std::thread with static linking causes segmentation fault

本文关键字:分段 错误 线程 静态 链接 启动 std      更新时间:2023-10-16

为了学习c++11(和boost),我正在使用boost asio和c++11(用于线程和lambdas)编写一个简单的http服务器。

我想测试新的c++11 lambdas和std::线程,所以我尝试在一个带有lambda:的std::螺纹中启动io_service.run()

#include <iostream>
#include <thread>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
using std::cout;
using std::endl;
using boost::asio::ip::tcp;
class HttpServer
{
public:
    HttpServer(std::size_t thread_pool_size)
    : io_service_(),
    endpoint_(boost::asio::ip::tcp::v4(), 8000),
    acceptor_(io_service_, endpoint_)
    { }
    void Start() {
        acceptor_.listen();
        cout << "Adr before " << &io_service_ << endl;
        std::thread io_thread([this](){
            cout << "Adr inside " << &io_service_ << endl;
            io_service_.run();
        });
        io_thread.join();
    }
private:
    boost::asio::io_service io_service_;
    tcp::endpoint endpoint_;
    tcp::acceptor acceptor_;
};
int main() {
    HttpServer server(2);
    server.Start();
}

这以分段故障结束。此外,有时它在lambda内部运行cout,有时不运行(尽管endl应该刷新)。在任何情况下,它都会打印io_service_的正确地址。但是,当我用boost::thread替换std::thread时(没有其他更改!),一切都很好。

如果有人知道问题的原因(可能是asio、std::thread或std::lambda),我将不胜感激。

附加信息:

根据另一篇文章,当捕获this时,在lambda内访问成员io_service_是可以的,就像我所做的那样

我在Ubuntu上运行gcc 4.6.1和boost 1.46。G++参数:

g++ -std=c++0x -static -I/home/andre/DEV/boost_1_48_0/include/ -L/home/andre/DEV/boost_1_48_0/lib/ -o webserver main.cpp -lboost_system -lboost_thread -lpthread

更新:

删除-静态修复了问题。我发现这个问题与boost或lambdas无关,只要构建static并使用std::thread,就可以进行复制。无论出于何种原因,这种组合都不起作用。我认为这篇文章描述的内容几乎相同,但我并不真正理解细节,错误信息也不同。

所以我想知道为什么std::thread和静态链接似乎不能一起工作。这里不允许静态链接是有原因的吗?我更新了问题标题并删除了提升标签。

将您的应用程序与-Wl,--whole-archive -lpthread -Wl,--no-whole-archive链接点击此处了解更多信息https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52590它对我有效。

删除-静态解决了问题。我发现它与boost或lambdas无关,而是与静态链接和std::thread有关,由于任何未知的原因,它们似乎无法协同工作(另请参阅这篇可能相关的文章)。

我想他们为什么不合作的问题虽然很有趣,但目前还不在讨论范围内,我很高兴得到了答案,所以这可以标记为已回答。