- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我一直在为 Linux 开发多线程套接字服务器,我正在尝试不同的方法来多路复用 I/O,看看哪种方法效果最好。
我已经有了创建共享 epoll/套接字的代码 - 启用了 EPOLLONESHOT - 每个线程都从中提取事件,然后在处理后重新武装 fd 上的 EPOLLONESHOT。
(“处理”,在这种情况下,意味着读取直到 EAGAIN/EWOULDBLOCK,然后发回一个简单的回复。基本上,我使用“ab”来测试它,所以它发送一个 HTTP GET 请求,我发送一个返回 HTTP“200 OK”。)
但我想试试 SO_REUSEPORT。所以每个线程都有自己的 epoll/socket,绑定(bind)到同一个端口。实际上,每个线程都是它自己的“迷你服务器”,我们让内核在它们之间进行负载平衡。
我执行了一个 accept(),为传入连接获取一个 fd,因此我将其添加到 epoll。一旦对该 fd 进行了处理,我自然会调用 close() 来结束对话。
但这似乎间歇性地丢弃传入的接受(并且“间歇性地”我的意思是它表现得像一个竞争条件 - 有时有效,有时无效,以随机方式)。
阅读这篇文章,显然有一个已知的错误,即 accept() 和 close() 之间可能存在竞争条件,因为 close() 导致事物的重新平衡并且接受队列刚刚重置,因此它们被丢弃.
我正在尝试解决这个问题。
我的一个想法是将 accepts 从 epoll 处理队列中分离出来,这样关闭 epoll 上的 fd 就不会清除该队列中的 accepts。
但这在逻辑上是行不通的,因为我不能让一个线程同时阻塞 accept() 和阻塞 epoll_wait()。为了正确地多路复用,我们必须阻止所有事件。
我得到的方法是,有多少个核心,就有多少个“迷你服务器”,每个核心都固定在一个核心上。因此,它们实际上是并行运行的,没有上下文切换。
这意味着虽然我可以生成一个新线程来处理新传入的 fd - 并让主线程在循环中只接受 accept() - 但是这在某种程度上违背了固定 CPU 的目的,并且多路复用的整个想法是摆脱“每个连接一个线程”的事情。
我查找了 SO_REUSEPORT 服务器的源代码,看看其他人如何处理这个问题,但我所能找到的只是一个简单的演示,它不是多线程/多核的。
有谁知道我如何解决这个问题才能使多线程 SO_REUSEPORT 套接字服务器真正工作?
最佳答案
当我测试自己的服务器代码时,我的注意力集中在服务器上。自然够了。
但注意到我在 Internet 上找到的一个示例,该示例设置了 SO_RCVTIMEO
套接字选项 - 接收超时 - 在将套接字 fd 从 accept 添加到 epoll 之前,我也尝试过这个,现在它所有运行都没有问题(1000 个并发的 100 万个请求,每个核心的使用率稳定在 30-40% 左右)。
我很想知道为什么这有固定的东西,但我认为这只是我的服务器不能容忍通信客户端的延迟、问题等,所以它卡在了通信中的任何问题 - 然后它将永远等待,因为没有超时。
为所有操作添加超时是有意义的 - 以防万一 - 因为网络通信从来都不是 100% 完美的。而且,一如既往地在编码中,无论如何都应该将所有输入视为不可靠且可能是恶意的。
关于linux - SO_REUSEPORT 套接字服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52269544/
我一直在为 Linux 开发多线程套接字服务器,我正在尝试不同的方法来多路复用 I/O,看看哪种方法效果最好。 我已经有了创建共享 epoll/套接字的代码 - 启用了 EPOLLONESHOT -
我正在使用 boost 库开发多进程套接字服务器。 每个进程运行一个 io_service . 我希望这个进程都在同一个端口上接受。 我知道 SO_REUSEPORT (在 linux 内核 3.9
我正在学习 SO_REUSEPORT 套接字选项,当我阅读“https://lwn.net/Articles/542629/”时,我对这句话感到困惑:“这简化了在客户端和服务器之间进行有状态对话的任务
我想知道标志 SO_REUSEPORT 的整数值。 在搜索时我找到了 here SO_REUSEPORT 已由值 0x0200 定义,这意味着 512,而在其他地方它是 SO_REUSEPORT 15
例如 linux kernel-2.6.32-279 没有在/usr/include/asm-generic/socket.h 中定义 SO_REUSEPORT 但 kernel-2.6.32-431
我想知道在 LINUX 2.6 中是否启用了 SO_REUSEPORT 选项?? 如果我尝试使用它并编译我的代码,我会收到以下错误 01.c:72: error: `SO_REUSEPORT' und
运行模拟器时出现以下错误,调试也不起作用,它说正在等待调试器附加。我想知道以下是否与陷入“等待调试器附加”有关。 Emulator: E0516 21:01:34.057349753 3279 soc
在旧版本的 Mac OS X 中,通配符绑定(bind)的工作方式如下所述: Socket options SO_REUSEADDR and SO_REUSEPORT, how do they dif
简而言之,SO_REUSEPORT 套接字选项允许在 ip:port 对上创建多个套接字。例如,program1和program2都可以调用函数链socket()->bind()->listen()-
在关于 SO_REUSEPORT 的讨论中,以下问题已发布到 reddit ,却无人接听。我想知道 Stack Overflow 是否知道答案。 Can anyone tell me how this
我有一个基于 libuv 的 C 语言 UDP 服务器,我们有一个: Main Thread:接收一个 UDP 数据包,将其排入 4 个队列之一,并调用对 4 个 worker 之一的出队回调。主线程
我已经阅读了 std::net 和 mio 的文档,并且发现了一些方法,例如 set_nodelay 和 set_keepalive,但我还没有找到在给定套接字上设置其他套接字选项(如 SO_REUS
Linux 内核 >= 3.9 允许通过设置 SO_REUSEPORT 在具有内核负载平衡的进程之间共享套接字:http://lwn.net/Articles/542629/ 这如何用于 AF_UNI
我的 Linux 应用程序需要以大约每秒 600,000 个数据包的速度接收一个包含中等大小数据包 (~1 KB) 的 UDP 流。我当前的实现是幼稚的:它有一个简单地调用 recv() 的线程。重复
我发现多个答案建议在多个 UDP 客户端需要监听同一端口上的广播时使用 SO_REUSEPORT 套接字选项。但是,我收到此选项不可用的错误消息。使用 python 2.7 from socket i
我对不使用 Elixir/Erlang 热升级的零停机部署系统感兴趣(由于代码运行时数据迁移的复杂性)。 我听说我可以在将服务器绑定(bind)到适配器时使用 SO_REUSEPORT 选项,这样我就
我正在学习套接字编程 tutorial出现了以下代码 // Forcefully attaching socket to the port 8080 setsockopt(server_fd, SOL
我正在编写一个多进程 UDP 服务器,它使用 SO_REUSEPORT 让多个工作进程监听同一个端口。 有没有办法告诉内核我希望根据数据包的源地址将数据包一致地传送到进程? (服务器需要根据源地址保存
考虑这段代码: #include #include #include #include #include #include #include #include #define SERV
我试图在 Ubuntu 20.04 上安装没有 Android Studio 的 SDK 和 Emulator。 但是被这个错误卡住了。 E0520 11:06:29.866803544 526
我是一名优秀的程序员,十分优秀!