gpt4 book ai didi

c++ - 有没有更好的方法在 C++ 中使用异步 TCP 套接字而不是轮询或选择?

转载 作者:可可西里 更新时间:2023-11-01 02:31:21 24 4
gpt4 key购买 nike

我最近开始编写一些使用套接字的 C++ 代码,我希望它是异步的。我读过很多关于如何使用 poll 和 select 使我的套接字异步(使用 poll 或 select 等待发送或接收缓冲区)的文章,但在我的服务器端我有一个 struct pollfd 数组,每次监听套接字接受一个连接,它将它添加到 struct pollfd 的数组中,以便它可以监视该套接字的 recv (POLLIN)。

我的问题是,如果我有 5000 个套接字连接到我的服务器上的监听套接字,那么 struct pollfd 数组的大小将是 5000,因为它将监视所有连接的套接字,但这是我知道的唯一方法检查套接字的 recv 是否准备就绪,方法是循环遍历 struct pollfd 数组中的所有项目,以找到其 revents 等于 POLLIN 的项目。当连接的套接字数量非常大时,这似乎有点低效。有更好的方法吗?

boost::asio 库如何处理 async_accept、async_send 等...?我该如何处理?

最佳答案

搞什么鬼,我先写个答案吧。

我将忽略“异步”与“非阻塞”术语,因为我认为它与您的问题无关。

您在处理数以千计的网络客户端时担心性能问题,您的担心是对的。你重新发现了 C10K problem .当 Web 还很年轻时,人们发现需要少量快速的服务器来处理大量(相对)慢速的客户端。现有的选择/轮询类型接口(interface)需要对所有套接字进行线性扫描——在内核和用户空间中——以确定哪些套接字就绪。如果许多套接字经常空闲,您的服务器可能会花费更多时间来确定要做什么而不是实际工作。

快进到今天,我们基本上有两种方法来处理这个问题:

1) 每个套接字使用一个线程,只发出阻塞读写。在我看来,这通常是最简单的编码方式,而且现代操作系统非常擅长让空闲线程安静地休眠,而不会造成任何显着的性能开销。根据我的经验,这种方法对数百个客户非常有效;我个人不能说它对数千人有何作用。

2) 使用为解决 C10K 问题而引入的特定于平台的接口(interface)之一。这意味着 epoll (Linux)、kqueue (BSD/Mac) 或完成端口 (Windows)。 (如果您认为 epollpoll 相同,请再看一遍。)所有这些只会通知您的应用程序有关实际准备好的套接字,避免了浪费的线性扫描空闲连接。有几个库可以使这些特定于平台的接口(interface)更易于使用,包括 libevent、libev 和 Boost.Asio。您会发现,只要这些接口(interface)可用,它们最终都会在 Linux 上调用 epoll,在 BSD 上调用 kqueue,等等。

关于c++ - 有没有更好的方法在 C++ 中使用异步 TCP 套接字而不是轮询或选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34623093/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com