2012-01-25 28 views
10

要學習C++ 11(和boost)我正在使用boost asio和C++ 11(用於線程和lambdas)編寫一個簡單的http-server。使用靜態鏈接啓動std ::線程會導致分段錯誤

我想測試新的C++ 11個lambda表達式和std ::線程,所以我試圖用一個lambda開始io_service.run()像這樣一個std ::螺紋:

#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訪問拉姆達內構件io_service_捕獲this時,因爲我做它是好的。

我在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或lambda無關,只要構建靜態和使用std::thread即可複製。由於任何原因,此組合不起作用。 我認爲這個post描述幾乎相同,但我不明白的細節和錯誤信息是不同的。

所以我想知道爲什麼std::thread和靜態鏈接似乎不起作用。是否有一個靜態鏈接不允許在這裏的原因?我更新了問題標題並刪除了boost標籤。

+0

我知道上面的代碼在這個時候什麼都不做。我只留下了與所描述問題相關的內容...... –

+0

您是否嘗試過在調試器中運行它以查看分段錯誤的位置? –

+1

@JoachimPileborg對不起,錯過了。段錯誤有時在lambda的第一行(cout << ...)和第二行的其他時間(io_service_.run();)中。最後我發現它與boost或lambdas無關,但是使用靜態鏈接和std :: thread。移除 - 靜態解決了這個問題。我發現了一個類似的帖子來描述這些[問題](http://stackoverflow.com/questions/7090623/c0x-thread-static-linking-problem)。 –

回答

6

移除 - 靜態解決了這個問題。我發現它與boost或lambdas沒有關係,但是有靜態鏈接和std::thread,它們似乎並不是因爲任何未知的原因一起工作(也可能與此post有關)。

我想他們爲什麼不一起工作的問題 - 儘管有趣 - 現在已經超出了範圍,我很高興回答,所以這可以標記爲已回答。

6

將您的應用程序鏈接到-Wl,--whole-archive -lpthread -Wl,--no-whole-archive 更多這裏https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52590 它適用於我。

+2

它的一個哭泣的恥辱,即使在gcc 6.2中,僅僅與'-static -pthread'鏈接的結果將導致破壞的可執行文件(即運行時錯誤)並且沒有鏈接器錯誤甚至警告。而且我必須花費幾個小時的時間才能發現這個問題,因爲gcc 4.7已經解決了,並且被解析爲「RESOLVED INVALID」。你的回答最終指出我做錯了什麼。 – Julian

+1

你是一個拯救生命的人。謝謝! –