【发布时间】:2012-07-17 22:26:28
【问题描述】:
我正在学习使用 Boost ASIO。这是从chat example 中复制的一些代码以及 Boost ASIO 文档,
typedef std::deque<chat_message> chat_message_queue;
class chat_client
{
public:
chat_client(boost::asio::io_service& io_service,
tcp::resolver::iterator endpoint_iterator)
: io_service_(io_service),
socket_(io_service)
{
boost::asio::async_connect(socket_, endpoint_iterator,
boost::bind(&chat_client::handle_connect, this,
boost::asio::placeholders::error));
}
void write(const chat_message& msg)
{
io_service_.post(boost::bind(&chat_client::do_write, this, msg));
}
void close()
{
io_service_.post(boost::bind(&chat_client::do_close, this));
}
private:
void handle_connect(const boost::system::error_code& error)
{
//Implementation
}
void handle_read_header(const boost::system::error_code& error)
{
//Implementation
}
void handle_read_body(const boost::system::error_code& error)
{
//Implementation
}
void do_write(chat_message msg)
{
bool write_in_progress = !write_msgs_.empty();
write_msgs_.push_back(msg);
if (!write_in_progress)
{
boost::asio::async_write(socket_,
boost::asio::buffer(write_msgs_.front().data(),
write_msgs_.front().length()),
boost::bind(&chat_client::handle_write, this,
boost::asio::placeholders::error));
}
}
void handle_write(const boost::system::error_code& error)
{
//Implementation
}
void do_close()
{
socket_.close();
}
private:
boost::asio::io_service& io_service_;
tcp::socket socket_;
chat_message read_msg_;
chat_message_queue write_msgs_;
};
写入是异步的,在成员变量
write_msgs_和read_msgs_周围没有使用锁。这里不应该有并发的问题吗?从运行
io_service::run?的线程调用post是否安全,那么dispatch呢?如果从未运行io_service::run的线程进行相同的调用呢?在
doSend(),为什么他们将消息推送到write_msgs_而不是直接发送?同样在同一个函数中,他们为什么要检查write_msgs_是否为空,并且只有在不是时才继续发送?write_msgs_.empty() = false是否表示正在进行写入?怎么样?如果
do_write()仅在一个线程中被调用,那么为什么我需要一个队列来维护一系列发送?io_service不会完成手头的任务,然后执行do_write调用的异步操作吗?使用dispatch代替post会在上述示例中产生影响吗?
【问题讨论】:
-
嗨沉,我也在学习asio。你成功编译你的代码了吗?当我尝试聊天示例时,编译器说:‘async_connect’不是‘boost::asio’的成员。 (我使用的是 asio 1.41.3)。
-
@SonDo 我可以编译代码。您是否包含所有必要的标题?
-
嗨@sank,我想通了。我使用了旧版本的 asio(boost 1.42),其中 async_connect 属于不同的类(套接字)。谢谢。
-
聊天示例是异步的,但不是并发的。这是典型的反应堆。
标签: c++ boost concurrency boost-asio