2012-01-25 5 views
10

C++ 11 (및 부스트)을 배우려면 boost asio 및 C++ 11 (스레딩 및 람다 용)을 사용하는 간단한 http-server를 작성하고 있습니다. 이 분할로 종료정적 링크로 std :: thread를 시작하면 세그먼트 화 오류가 발생합니다.

#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(); 
} 

:

나는 새로운 C++ 11 람다 및 표준 : : 스레드를 테스트 할 수는 그래서 람다와 표준 : : 스레드에서이 같은 io_service.run()을 시작하려 결점. 또한 때로는 람다 내부에서 큐 아웃을 실행하는 경우가 있습니다 (endl은 플러시해야 함). 어쨌든 올바른 주소는 io_service_입니다. 그러나 std::threadboost::thread으로 바꿀 때 (다른 변경은 없습니다!) 모든 것이 잘 작동합니다.

누군가가 문제가 발생한 곳 (asio, std :: thread 또는 std :: lambda 일 수 있음)이 있으면 감사하게 생각합니다.

추가 정보

: 그것을 마찬가지로, this 촬영시 람다 내의 부재 io_service_ 액세스 다른 post 따르면

괜찮다.

저는 우분투에서 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 제거하여 문제를 해결했습니다. 나는 그 문제가 부스트 나 람다와 관련이 없으며 언제든지 정적으로 구축하고 std::thread을 사용할 때마다 재현 될 수 있다는 것을 알게되었습니다. 어떤 이유로이 조합은 작동하지 않습니다. 이 부분은 post으로 거의 동일하다고 생각합니다. 그러나 세부 사항을 이해하지 못하고 오류 메시지가 다릅니다.

그래서 std::thread과 정적 링크가 함께 작동하지 않는 이유가 궁금합니다. 정적 링크가 허용되지 않는 이유가 있습니까? 질문 제목을 업데이트하고 부스트 태그를 제거했습니다.

+0

위의 코드는 현재 아무 것도하지 않는다는 것을 알고 있습니다. 설명 된 문제와 관련이있는 것만 남겼습니다 ... –

+0

세그먼트 화 오류가있는 곳을 디버거에서 실행 해 보았습니까? –

+1

@ JoachimPileborg 죄송합니다. segfault는 때로는 람다 (cout << ...)의 첫 번째 줄과 두 번째 줄의 다른 시간 (io_service_.run();)에있었습니다. 마지막으로 나는 boost 또는 lambdas와는 아무런 관련이 없다는 것을 알았지 만, static linking과 std :: thread를 가지고있다. -static을 제거하면 문제가 해결되었습니다. 같은 [문제] (http://stackoverflow.com/questions/7090623/c0x-thread-static-linking-problem)를 설명하는 유사한 게시물을 발견했습니다. –

답변

6

-static을 제거하면 문제가 해결됩니다. 나는 부스트 나 람다와 아무 관련이 없다는 것을 알았지 만 정적 링크와 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

당신은 생명의 은인입니다. 감사! –

관련 문제