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

时间:2012-01-25 11:53:32

标签: c++ c++11

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

我想测试新的c ++ 11 lambdas和std :: thread,所以我尝试在带有lambda的std :: thread中启动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_的正确地址。但是,当我用std::thread替换boost::thread时(没有其他更改!),一切正常。

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

其他信息:

根据另一个post访问成员,在抓取this时,lambda中的io_service_正常,就像我一样。

我在Ubuntu上运行gcc 4.6.1并提升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

更新

删除-static修复了问题。我发现问题与boost或lambdas无关,并且可以在构建静态和使用std::thread时重现。出于任何原因,这种组合不起作用。 我认为这个post描述的几乎相同,但是我不太了解细节,错误信息也不同。

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

2 个答案:

答案 0 :(得分:7)

将您的应用与-Wl,--whole-archive -lpthread -Wl,--no-whole-archive相关联 更多https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52590 它对我有用。

答案 1 :(得分:6)

删除-static解决了这个问题。我发现它与boost或lambdas没有任何关系,但是使用静态链接和std::thread,它们似乎不会因为任何未知原因而一起工作(另请参阅此post可能与之相关)。

我猜他们不能一起工作的问题 - 虽然很有趣 - 现在超出了范围,我对答案很满意,所以这可以标记为已回答。