2

我有一个名为 overlay_server 的类,它有一个公共方法

void member_list_server(boost::asio::io_service &io_service){

现在我想在一个新线程中运行它。所以我创建了一个新线程,并在其构造函数中使用了 bind。

在我在 void member_list_server 函数中创建 io_service 之前。但是现在我正在尝试在 main 中创建一个 io_service 对象并将其传递给我得到错误的这个线程?

  int main(){

    boost::asio::io_service io_service_;

    overlay_server overlay_server_(8002);
    boost::thread thread_(
        boost::bind(&overlay_server::member_list_server, overlay_server_, io_service_)
        );
  1. 为什么我会收到错误消息

    错误 C2248:“boost::noncopyable_::noncopyable::noncopyable”:无法访问在类“boost::noncopyable_::noncopyable”中声明的私有成员

  2. 我还将创建需要 io_service 的其他类的实例。最好的方法是什么,我应该在 main 中创建一个 io_service 对象并将其传递给所有线程吗?

或者在我将来创建的所有线程中创建一个单独的线程?

4

1 回答 1

1

问题是您通过值而不是通过引用传递 boost::asio::io_service 对象。这意味着应该调用 boost::asio::io_service 默认复制构造函数,这对于 io_service 是不允许的。

一种选择是将指针传递给 boost::asio::io_service 对象。以下是我的一些代码:

void Model::TcpPortListener (boost::asio::io_service &io_service, 
                             boost::asio::ip::tcp::acceptor &a, 
                             boost::asio::ip::tcp::endpoint &lep, 
                             SocketObject *readSocketObject)
{
    boost::asio::ip::tcp::acceptor *b = &a;
    boost::asio::io_service *s = &io_service;
    . . .
    boost::asio::ip::tcp::socket *sock (new boost::asio::ip::tcp::socket (io_service));

    a.async_accept (*sock, boost::bind (&Model::HandleRemoteAccept, this, s, b, sock, lep, boost::asio::placeholders::error));
}

void Model::HandleRemoteAccept (boost::asio::io_service *io_service, 
                                boost::asio::ip::tcp::acceptor *a, 
                                boost::asio::ip::tcp::socket *sock, 
                                boost::asio::ip::tcp::endpoint &lep, 
                                const boost::system::error_code& error)
{
    . . .
    // Continue listening
    TcpPortListener (*io_service, *a, lep, 0);
}

要观察的要点是:

  1. 在 Model::TcpPortListener() 中,'s' 被分配了 io_service 的地址
  2. 在同一个函数中,'s' 作为第三个参数传递给 boost::bind()。因为它是一个地址而不是一个对象,所以没有调用默认的复制构造函数。
  3. 在 Model::HandleRemoteAccept() 中,io_service 被取消引用并传递给 TcpPortListener() 函数。

其他人提出的关于悬空引用的观点很重要,你应该好好解释一下。

于 2013-05-30T09:52:23.733 回答