我一直在运行一个 C 程序,它偶尔会连接到 Redis 数据库。运行程序几个小时后,它显示“无法创建套接字:打开的文件太多”。我非常确定每次完成数据库中的逻辑部分后我都会关闭连接。所以我想知道是否有任何方法可以知道 C 程序在运行时创建了多少个套接字?我使用的是 Ubuntu 16.04。
答案1
您没有指定操作系统,并且/proc/*/fd/
并不存在于所有操作系统上。
您实际上需要列出该进程当前打开的所有文件描述符,从中您可以确定实际泄漏的内容。泄漏的不一定是套接字文件描述符。
在 FreeBSD、NetBSD、OpenBSD 上……
…及其各种衍生产品(例如 TrueOS、DragonFly BSD)。
使用fstat
带有-p
选项和相关进程 ID 的命令:
fstat -p 718
fstat
。NetBSD通用命令手册。 2013年12月15日。
在 AIX 上
类似地使用该procfiles
命令,并带有-n
打印名称的选项:
procfiles-n 6679
procfiles
。操作系统7.2。 IBM 知识中心。
在 OpenSolaris 上...
……因此,关于 Illumos、Schilix 等人。
使用pfiles
命令:
pfiles 13253
pfiles
。 用户命令。 SunOS 10.5 手册。 2008年12月10日。
在 Linux 上
类似地使用lsof
命令:
lsof -p 41467
此外
在我的 C++ 程序中,一个拥有文件描述符并在其析构函数中关闭它的简单类会产生奇迹。不幸的是,您必须求助于 GNU 特定的语言扩展(即__attribute__(__cleanup__)
)才能在 C 程序中实现这一点。
您当然可以使用其他工具更进一步。使用 DTrace 和合适的脚本,您可以在打开和关闭文件描述符时监视进程。 (您也可以使用truss
、 或ktrace
或 来执行此strace
操作;尽管它们选择所进行的系统调用子集的机制要么相当基本,要么根本不存在。您也可以使用调试器和一些合适的断点来执行此操作。)
答案2
在系统级别上,用什么语言编写程序并不更好。
查看/proc/«pid»/fd
会告诉您进程已打开的文件描述符总数(不仅仅是套接字),但这将是一个近似值。也许其他人可以告诉你套接字。
您还strace
可以使用它来跟踪您的进程进行的系统调用。strace «my-program» «program args…»
在节目中
添加一些日志记录:打开和关闭套接字时的 printf 到日志文件。