我有一个在 linux 系统上运行的多线程 linux 应用程序
该应用程序在不同的 Linux 系统和内核中成功运行,而从未注意到此问题。
我们目前正在使用这个内核
#ulimits -a
Linux AM38 4.9.0-8-rt-amd64 #1 SMP PREEMPT RT Debian 4.9.130-2 (2018-10-27) x86_64 GNU/Linux
我们已经使用这个内核 1 年了,没有任何问题。
应用程序可以有一些外部连接的客户端。当客户端连接时,每个客户端都会创建几个线程。
最近我遇到了一个问题,pthread_create 返回 EAGAIn。我设法设计了一个重现失败的压力测试。重现需要2个小时。与生产失败所花费的时间相似。
一旦我能够重现问题,我就回到了生产中使用的版本,没有问题,但现在旧版本也出现了问题。所以我认为我们一直都有问题,但我们现在有一个突出问题的用户案例。
基本上,该测试模拟通信中断 30 秒,因此所有客户端都断开连接,然后我让系统再正常工作 30 秒,以便客户端重新连接。我添加了 450 毫秒的延迟,以便在尝试重新连接时进一步增加压力。只有 30 个客户。
在生产和我的压力实验室条件下,问题在开始对系统施加压力 2 小时后出现。
我已经检查了僵尸以确保我正确地加入了线程。 htop 或 ps 从不将任何线程显示为 Z 或 defunct。
我用 htop 监控了系统,我从未在系统中看到超过 46 个任务和 140 个线程。
我检查了系统限制,看起来没问题。
# ulimit -a
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 31414
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 31414
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
# cat /proc/sys/kernel/pid_max
327687
# cat /proc/sys/kernel/threads-max
62828
# free -h
total used free shared buff/cache available
Mem: 7.7G 470M 3.7G 83M 3.5G 7.0G
Swap: 0B 0B 0B
如果我做一个 ps 看起来像
# ps -axH | grep myapplication
3910 tty5 Sl+ 4:23 myapplication -v
3910 tty5 Sl+ 1:41 myapplication -v
3910 tty5 Sl+ 0:02 myapplication -v
3910 tty5 Sl+ 0:00 myapplication -v
3910 tty5 Sl+ 0:46 myapplication -v
.... same looking lines here
3910 tty5 Sl+ 0:00 myapplication -v
3910 tty5 Sl+ 0:47 myapplication -v
3910 tty5 Sl+ 0:00 myapplication -v
3910 tty5 Sl+ 0:48 myapplication -v
3910 tty5 Sl+ 0:00 myapplication -v
3910 tty5 Sl+ 0:49 myapplication -v
3910 tty5 Sl+ 0:51 myapplication -v
线程总数:134
我可以连接到系统并执行程序,并且系统上的网络服务器运行。只有那个过程似乎失败了。
如果我停止/启动该过程,再过 2 小时一切都会恢复正常。
在这里pthread_create fails with EAGAIN我发现我可能会遇到这个错误
https://bugzilla.kernel.org/show_bug.cgi?id=154011
但我不知道如何确认它以及如何解决我的问题。它似乎没有固定。
建议?
最佳答案
我已经找到它了。
我不是在一个地方调用 join_thread,但我希望看到线程作为 ps 的 zoombies,这个问题 stackoverflow.com/questions/31765867/... 给了我看的地方。
我发现确认问题的最佳提示是虚拟内存使用情况。在我的例子中,未加入的线程增加了保留的虚拟内存量。我的应用程序是 32 位的,所以一旦我们获得 4GB 的虚拟内存,游戏就结束了。 只需执行 htop 即可轻松查看线程虚拟内存使用情况。
我找到的链接提出了一种技术,如果您可以修改源代码并且直接使用 pthread 函数,它可以为您提供泄漏位置的答案。
Virtual memory increased 是一种间接数据,可以在生产中引发有关失败原因的标志。
感谢大家的帮助。
关于linux - pthread_create 在执行 2 小时后因 EAGAIN 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57446527/