简体   繁体   中英

C++ asio provide async execution of thread

I got a simple server app. When new client connecting, it handles request from client and send data back to it. My problem is to provide a async execution of handle thread. Now, when began a handle thread it stops acceptor loop and wait for return of corresponding function. The question is how to organize the continuation of acceptor loop (to be able to simultaneously handle other connection) after starting a handle thread?

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
}

So why do you call join? Join is about waiting for a thread to finish, and you say you don't want to wait for the thread, so, well... just don't call join?

You have two main problems here:

  1. Thread joining - you are waiting for thread finish before accept new connection
  2. Using pointer to a socket created on a stack

I recommend you this changes:

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

And HandleRequest will change to this:

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

You can also store thread somewhere and join it later instead of detaching.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM