linux - 如何在套接字关闭时唤醒 select()?

标签 linux multithreading sockets pthreads posix

我目前正在使用选择循环来管理代理中的套接字。这个代理的要求之一是,如果代理向外部服务器发送消息并且在一定时间内没有得到响应,则代理应该关闭该套接字并尝试连接到辅助服务器。关闭发生在一个单独的线程中,而选择线程阻塞等待事件。

我无法弄清楚如何检测此套接字是否已明确关闭,以便我可以处理故障。如果我在另一个线程中调用 close(),我会得到一个 EBADF,但我不知道哪个套接字已关闭。我试图通过异常 fdset 检测套接字,认为它会包含已关闭的套接字,但我在那里没有得到任何返回。我还听说调用 shutdown() 会向服务器发送一个 FIN 并收到一个 FIN,这样我就可以关闭它;但关键是我试图关闭它,因为在超时期限内没有得到响应,所以我也不能这样做。

如果我的假设有误,请告诉我。任何想法将不胜感激。

编辑: 针对有关使用select time out的建议:我需要异步关闭,因为连接到代理的客户端会超时,我不能等待select被轮询。只有当我将选择超时设置得非常短时,这才会起作用,这将不断地轮询并浪费我不想要的资源。

最佳答案

一般来说,我只是在另一个线程中标记要关闭的套接字,然后当 select() 从事件或超时返回时,我运行一个清理 channel 并关闭所有死连接并更新 fd_set。以任何其他方式执行此操作会使您面临放弃连接的竞争条件,就像 select() 最终为其识别了一些数据,然后关闭它,但另一个线程尝试处理检测到并获取的数据发现连接已关闭而感到沮丧。

哦,就不必复制尽可能多的数据而言,poll() 通常优于 select()。

关于linux - 如何在套接字关闭时唤醒 select()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1329453/

相关文章:

.net - Azure Functions 在函数内调用 http post

c - 重新附加到 Linux 中的进程

linux - USB : gadget : device mode : configfs: uvc and mass storage on single configuration?

linux - 在 bash 脚本中打印子字符串

c - 如何获取 Win32 中的核心数?

java - volatile 数组列表未按预期运行

sockets - Docker在高负载下阻止传出连接?

linux - 在 htop 中更改或隐藏进程名称

java - 从内部匿名 Runnable 访问外部变量

linux - socket() 域参数 : AF_* vs. PF_*