如何在boost :: asio中停止之前确保所有async_handler都已完成?

时间:2012-11-16 08:29:48

标签: c++ boost boost-asio

我的课程接收者...收到一些字符串并将其推送到缓冲区。

Reciever::Reciever(boost::shared_ptr<TSBuffer<std::string>> buffer, int port)
    : port(port), buffer(buffer)
{
    using namespace boost::asio;
    acceptor_ = new ip::tcp::acceptor(iosev, ip::tcp::endpoint(ip::tcp::v4(),  port));
}


Reciever::~Reciever()
{
    delete acceptor_;
}

void Reciever::run()
{
    using namespace boost::asio;
    _start();
    iosev.run();
}

void Reciever::stop()
{
    Sender s("127.0.0.1", std::string(8, '$'), port);
}

void Reciever::_start()
{
    using namespace boost::asio;
    boost::shared_ptr<ip::tcp::socket> socket(new ip::tcp::socket(iosev));
    acceptor_->async_accept(*socket, boost::bind(&Reciever::acceptHanlder, this, socket));
}

void Reciever::acceptHanlder(boost::shared_ptr<boost::asio::ip::tcp::socket> socket)
{
    std::string delim(8, '$');
    boost::system::error_code ec;
    boost::asio::streambuf strmbuf;

    boost::asio::read_until(*socket, strmbuf, delim, ec);
    std::istream is(&strmbuf);
    std::string re((std::istreambuf_iterator<char>(is)),std::istreambuf_iterator<char>());
    re.replace(re.end() - delim.size(), re.end(), "");
    if (re.size() && re != std::string(8, '$')){
        buffer->push(re);
        _start();
}

在main()函数中,我使用X(不确定)线程将X字符串发送给Reciever。当Reciever :: acceptHanlder被调用X次(这意味着处理X字符串)时,我想停止接收器(调用Reciever :: stop)。 但我不知道如何确定?

1 个答案:

答案 0 :(得分:2)

我发现在 acceptHanlder 的最后一行之前无法调用 async_accept 。因此,您可以在收件人对象中简单地实施一个计数器,并在作业完成时不要调用 _start 。当在不同的线程中使用相同的接收器时,它更复杂,我更喜欢使用“对象连接”范例。

此外,您可以使用 asio :: strand 来限制acceptHanlder - s,因此任何时候只有一个acceptHanlder Reciever可以处于活动状态。这消除了Reciever内的并发问题。因此,您可以安全地拨打Reciever::stop(使用相同的)。