我第一次使用 Boost Asio,我有一个接受多个连接的应用程序,每个连接都在单独的线程中,并将数据读/写到单个 TCP 套接字。
我对sync方法的理解是,每个线程在使用fd之前,他们需要使用像
select()/WSAEventSelect()
,WaitForSingleObject()
这样的调用来确保它是空闲的。
所以同步方法需要等待资源变得可用。
但是异步方法呢?
假设我有一个套接字,并执行
async_accept()
来接受连接,async_read()
来接收连接,async_write()
来发送。由于在异步方法中,资源/套接字没有保留,我还需要等待它变得可用吗?
在这个问题的开头,我解释了我想要做什么,所以如果我对问题的理解以及接下来发生的事情不准确,请原谅。
谢谢理解
我认为你的大部分解释可悲的是都是颠倒的。挑选出最明显的:
我对sync方法的理解是,每个线程在使用fd之前,他们需要使用像
/select()
,WSAEventSelect()
这样的调用来确保它是空闲的。WaitForSingleObject()
相反,
select
(poll/epoll)对于异步事件处理(例如传入数据可用或错误条件)很有用。它们对于同步操作不使用/有用,因为它们只会阻塞,直到达到状态。
也许您想象内核实现了“好像”与线程同步原语同步。很公平,虽然可能不是很准确,但效果是:调用阻塞。
即使使用每个连接一个线程,这种通信方式也是有限的,因为它永远不允许全双工通信,这意味着某些协议容易出现死锁。
假设我有一个套接字,并执行
来接受连接,async_accept()
来接收连接,async_read()
来发送。由于在异步方法中,资源/套接字没有保留,我还需要等待它变得可用吗?async_write()
是和不是。如果您手动执行异步 BSD 套接字,是的,您实际上需要轮询套接字事件,如上所述。
Asio 的全部目的是以独立于平台的方式使其透明,同时还利用了大量的良好实践和优化。因此,NO您不需要等待[套接字]变得可用。
由于在异步方法中,资源/套接字不被保留
但确实如此。它由位于执行上下文中的服务实现保存 (
io_context
)。 tcp::socket
(或其他 basic_stream_socket
实例)是您的“句柄”。因此,套接字被保留,并且服务知道何时/如何等待低级状态/事件。
我可以给你一个例子,说明我如何实现你所描述的内容,但我在这个网站上已经显示了很多答案。如果您有更具体的问题,欢迎询问。