2016-10-15 4 views
1

私はシンプルなサーバーアプリケーションを手に入れました。新しいクライアントが接続するとき、それはクライアントからの要求を処理し、それにデータを戻します。私の問題は、ハンドルスレッドの非同期実行を提供することです。ハンドルスレッドを開始すると、アクセプタループを停止し、対応する関数の戻りを待ちます。 問題は、ハンドルスレッドを開始した後でアクセプタループの継続を(他の接続を同時に処理できるように)整理する方法ですか?C++ asioはスレッドの非同期実行を提供します

Server.h:

class Server 
{ 
private: 
    //Storage 
    boost::asio::io_service service; 
    boost::asio::ip::tcp::acceptor* acceptor; 
    boost::mutex mtx; 

    //Methods 
    void acceptorLoop(); 
    void HandleRequest(boost::asio::ip::tcp::socket* clientSock); 

public: 
    Server(); 
}; 

Server.cpp

void Server::acceptorLoop() 
{ 
    std::cout << "Waiting for clients..." << std::endl; 

    while (TRUE) 
    { 
     boost::asio::ip::tcp::socket clientSock (service); 
     acceptor->accept(clientSock); //new socket accepted 
     std::cout << "New client joined! "; 
     boost::thread request_thread (&Server::HandleRequest, this, &clientSock); //create a thread 
     request_thread.join(); //here I start thread, but I want to continue acceptor loop and not wait until function return. 
    } 
} 

void Server::HandleRequest(boost::asio::ip::tcp::socket* clientSock) 
{ 
    if (clientSock->available()) 
    { 
     //Works with socket 
    } 
} 

Server::Server() 
{ 
    acceptor = new boost::asio::ip::tcp::acceptor(service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 8001)); 
    acceptorLoop(); //loop started 
} 
+1

たとえば、ベクトルを作成し、スレッドを作成した直後は結合しません。また、 'clientSock'オブジェクトを処理する他の方法を使用する必要があります。なぜなら、今度はループが反復すると、スコープから外れて(破棄される)オブジェクトへのポインタを渡すからです。 –

答えて

1

あなたはここでは2つの主要な問題があります。

  1. スレッドが参加 - あなたが前スタック上に作成されたソケットにポインタを使用して新しい接続
  2. を受け入れるスレッド仕上げを待っている

この変更をお勧めします:

boost::asio::ip::tcp::socket clientSock (service); 
    acceptor->accept(clientSock); //new socket accepted 
    std::cout << "New client joined! "; 
    std::thread{std::bind(&Server::HandleRequest, this, std::placeholders::_1), std::move(clientSock)}.detach(); 

とのhandleRequestはこれに変更されます。

void Server::HandleRequest(boost::asio::ip::tcp::socket&& clientSock) 
{ 
    if (clientSock.available()) 
    { 
     //Works with socket 
    } 
} 

あなたはまた、どこかのスレッドを保管し、代わりに取り外しの後に、それに参加することができます。

1

なぜあなたは参加呼ぶのですか? Joinはスレッドが終了するのを待つことについてのことであり、スレッドを待つことを望まないと言うので、まあ... joinを呼び出さないでください。

関連する問題