【问题标题】:Unnecessary ioctl(n, TCGETS) Calls On Socket Handles套接字句柄上不必要的 ioctl(n, TCGETS) 调用
【发布时间】:2021-12-05 08:30:23
【问题描述】:

为什么 Perl5 似乎隐含地对各种文件句柄运行不必要的 ioctl() tty 检查?

据我了解,这是 Perl5 的长期特性,似乎没有人考虑对其进行更改。当我说更改时,我的意思是“对 Perl5 进行更改以促进对您知道不是 tty 句柄的文件句柄启用或禁用此类ioctl() tty 检查”。

我有一个 TCP/IP 套接字程序,在 accept() 返回一个新套接字后,下面的 strace 显示在新句柄上调用 ioctl()s。在这种情况下,ioctl() 调用是对 CPU 和负载的浪费。当然,如果accept()ioctl() 只被调用一次,那就没什么意义了。然而,随着时间的推移,多个进程、多个ioctl() 调用......这一切都加起来了。

是否有现成的方法来明确禁用对文件句柄和套接字等多余的ioctl() tty 检查?

如果无法禁用,是否有人认为这种禁用/启用检查的上下文功能值得?

这是strace 的摘录,显示了客户端套接字初始连接:

18:21:59.818126 select(8, [6], NULL, NULL, {tv_sec=10, tv_usec=0}) = 1 (in [6], left {tv_sec=9, tv_usec=999997})
18:21:59.818321 accept4(6, {sa_family=AF_INET, sin_port=htons(56124), sin_addr=inet_addr("127.0.0.1")}, [4096->16], SOCK_CLOEXEC) = 7
18:21:59.818419 fcntl(7, F_SETFD, FD_CLOEXEC) = 0
18:21:59.818453 ioctl(7, TCGETS, 0x7ffff5befcd0) = -1 ENOTTY (Inappropriate ioctl for device)

【问题讨论】:

  • 一个演示它的minimal reproducible example perl 脚本会很有用。并不是说我认为 ioctl 对性能有任何影响。还不如抱怨一下不必要的 fcntl。

标签: perl sockets ioctl


【解决方案1】:

所以你认为应该有一种方法告诉 Perl 检查句柄是否是一个套接字以跳过与套接字无关的执行代码。

你不应该告诉 Perl 这样做;它应该是自动的。它是自动的。对ioctl 的调用就是那个检查。

我认为有问题的电话来自this sub,它使用isatty 来检查应该使用哪种缓冲。如果是这样,则调用ioctl 用于检查句柄是否为套接字,以跳过与套接字无关的执行代码。

您是否建议有更好的方法来检查文件句柄是否是套接字?

【讨论】:

  • @zevekz,关于“不是检查 fd 是否为套接字的方法。”,答案并没有说它是。它检查它是否是套接字或其他东西。
  • @zevekz, Re "因为调用 accept(2) 或 socket(2) 的是 perl 本身,所以它知道返回的 fd 不能是 tty。"、acceptsocket 知道这不是 tty。但这根本没有帮助,因为不是 acceptsocket 进行检查。
  • @zevekz,关于“你的最后一段可能应该是修辞的”,事实并非如此。如果有更好的方法,可以提交罚单。 /// Re“会告诉你文件描述符是否是套接字”,我说的是更好的方法。您的反应好像 OP 询问“如何检查句柄是否为套接字”,但没有被问到。 OP 希望消除 ioctl 调用的成本,我怀疑用 getsockoptfstat 替换它会实现这一点。具体来说,我怀疑它是否为套接字提供了任何好处,并且对于某些非套接字仍然需要调用它 ioctl
  • @zevek。已经说过并回应了。 acceptsocket 知道这不是 tty。但这根本没有帮助,因为不是acceptsocket 进行检查。缓冲层是需要信息的,它从ioctl 获取信息。请参阅我上面链接的代码。
  • 不,不是,我已经说过两次了。我什至链接到这样做的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-19
  • 2015-09-19
  • 1970-01-01
  • 1970-01-01
  • 2011-02-10
  • 2013-08-02
  • 1970-01-01
相关资源
最近更新 更多