使用boost和asio运行线程

时间:2015-07-24 15:38:02

标签: c++ c++11 boost boost-asio

简介

我正在尝试创建一个线程来从套接字接收数据。

代码

void ClientTcp::read_handler(tcp::socket s){
    for(;;){
        char buffer[max_buffr];
        boost::system::error_code error;
        size_t length = s.read_some(boost::asio::buffer(buffer), error);
        if (error == boost::asio::error::eof)
            break; // Connection closed cleanly by peer.
        else if (error)
            throw boost::system::system_error(error); // Some other error.
        buffer[length] = '\0';
        std::cout << "-> " << buffer << std::endl;
    }
}

void ClientTcp::run(){
    tcp::socket s(io_service_);
    tcp::resolver resolver(io_service_);
    boost::asio::connect(s, resolver.resolve({ip_, port_}));

    boost::thread read_th(read_handler, std::move(s));
    std::string message;
    for(;;){
        std::cin >> message;
        boost::asio::write(s, boost::asio::buffer(message, message.size()));
    }
    read_th.join();
}

问题

这一行boost::thread read_th(read_handler, std::move(s));有一个我无法理解的错误。

错误 no matching function for call to boost::thread::thread(<unresolved overloaded function type, std::remove_reference<boost::asio::basic_stream_socket<boost::asio::ip::tcp>&>::type)

主要问题 我如何从类方法启动线程?

2 个答案:

答案 0 :(得分:2)

回答错误的问题:您使用boost::bind

boost::thread read_th(boost::bind(&ClientTcp::read_handler, this, std::move(s)));

但你肯定不想那样做。每个异步操作使用一个线程根本不起作用。

Boost让您在不需要额外线程的情况下实现异步。只需使用async_*函数代替您的函数 重新使用:

  • async_read_some
  • async_write

不要忘记运行io_service::run()

答案 1 :(得分:0)

似乎boost::thread构造函数无法执行&#34;完美转发&#34;它的论点(并且你不能使用bind作为@sehe答案的评论中描述的原因。)

但是,作为C ++ 11的一部分,std::thread确实正确转发了参数,因此以下编译:

#include <boost/asio.hpp>
#include <thread>

using namespace boost::asio;

void read_handler(ip::tcp::socket && s)
{
} 

int main()
{
    io_service io;
    ip::tcp::socket s(io);
    std::thread read_th(read_handler, std::move(s));
}

请注意,如果read_handler是非静态成员函数(如您的问题中所述),则应将其与对象实例绑定:std::thread(&ClientTcp::read_handler, this, std::move(s));

(当然,应该考虑对象的使用寿命,以及@sehe提出的设计考虑因素。)