写了一个循环函数,每次循环使用一个wandb.run记录数据。
最后报错 OSError: [Errno 24] Too many open files
。
国内用wandb的人好像还不是很多…隔壁tensorboard的为主。
自食其力。
可以用psutil库持续跟踪进程的句柄和描述符数量。
import psutil
def num_open_files():
s = psutil.Process()
num_open_files = len(s.open_files())
num_file_descriptions = s.num_fds()
return num_open_files ,num_file_descriptions
在我跑的代码中,
这个num open files的2,在wandb.finish()之后就清0了。
但是num_fds持续增加。
每过一个循环+4。
可以看出来问题还是在file description的数量上。这样一直增加下去,达到上限可不就报错了么。
通过命令可以查看当前进程(11448)下的所有文件描述符。
从这个图已经能看出来为什么每个循环num_fd会 +4了。
每个循环里,都会打开2个描述符,指向 ‘/dev/pts/92’ 。
然后打开2个描述符,指向2个wandb上传管道。
这样一共是4个fd。
符合观察。
我遇到的这个问题,
归根结底是wandb会持续打开新的连接,创建新的管道,向服务器传数据。
但python没有很好的自动回收机制处理这些句柄。
注意:python打开的文件描述符需要显式进行关闭。
这是python的特性决定的。
一般的文件操作中,我们用with scope的话,会自动关闭这个fd。
或者用os.close(file)自己关闭。
但wandb没有写好这个功能。只打开,不关闭。
(去提issue)
在官方解决这个问题之前,我们可以试着增加系统对文件描述符的限制。
linux默认一般是1024,每个循环+4,那么最多256个循环就满了。
硬限制是实际的限制,而软限制,是warnning限制,只会做出warning
分析句柄数,查找原因,这是解决问题最根本的办法。那么如何分析那,就需要用到lsof这个命令了(关于这个命令大家可以在网上学习学习)。
1 统计各进程打开句柄数:lsof -n|awk ‘{print $2}’|sort|uniq -c|sort -nr
2 统计各用户打开句柄数:lsof -n|awk ‘{print $3}’|sort|uniq -c|sort -nr
3 统计各命令打开句柄数:lsof -n|awk ‘{print $1}’|sort|uniq -c|sort -nr
Check Hard/Soft Limit in Linux
ulimit -Hn
ulimit -Sn
查看
ulimit -n
设置2个一起提高(直到下次reboot前有效)
ulimit -SHn 65535
写入文件
vim /etc/security/limits.conf
加两行
soft nofile 65535
hard nofile 65535
全局设置文件描述符数量
Check System wide File Descriptors Limits in Linux
整个系统所有用户的最大打开数量
cat /proc/sys/fs/file-max
26357916
可以直接vim
vim /proc/sys/fs/file-max
加一行
# To increase open file limit to 500000, the change remain active until the next reboot
sysctl -w fs.file-max=500000
# apply them permanently
vi /etc/sysctl.conf
# add the following line
fs.file-max=500000
# Users will need to logout and login again for the changes to take effect, if you want to apply the limit immediately, you can use:
sysctl -p
为单用户设置文件描述符数量
vi /etc/security/limits.conf
//https://www.cnblogs.com/feng0815/p/8620564.html
//https://www.tecmint.com/increase-set-open-file-limits-in-linux/