我有一个python程序需要扫描一些大的日志文件来提取有用的信息。
在这个程序中,为了更好地利用服务器(运行Ubuntu 12.04 LTS,拥有64个内核和96 GB内存)的计算资源, 我创build了一个大小为10的进程池,并向这些池工作者应用服务器。 每个作业使用file.readlines()
从几个大文件(每个大约file.readlines()
,共20个文件)中file.readlines()
,然后逐行分析以find有用的信息并将结果保存到字典中。 在所有文件被扫描和分析之后,结果字典被写入磁盘。 另外,在整个脚本中没有显式调用gc.collect()
。
我使用root账号在服务器上启动了这个程序,这些程序首先运行正常:这个程序的每个进程将占用大约3.8GB的内存,所以共有40GB
几个小时后, 其他用户启动另一个耗费内存的程序(也使用root帐户),它积极使用几乎所有的内存(占内存总量的99%),之后该程序被CTRL-Z
中断, killall -9 process_name
但是,在这之后,我发现我的大部分池工的进程状态已经改为S,这些睡眠进程的CPU使用率降为0.根据man top
:
The status of the task which can be one of: 'D' = uninterruptible sleep, 'R' = running, 'S' = sleeping, 'T' = traced or stopped, 'Z' = zombie
我使用ps -axl命令来检查进程正在hibernate的内核函数的名称, 事实certificate这些poolworker进程在_fastMutex
上_fastMutex
。
这种情况会持续很长一段时间(进程状态现在仍然是S),我不想重新启动我的进程再次扫描所有文件, 我怎么能改变这些进程从睡眠状态到运行?
睡觉状态表示他们正在等待某事; 唤醒它们的方式是满足它所等待的任何条件(互斥体可能是等待的机制,而不是条件本身)。 对内存消耗的引用表明了一些进程至少部分被分页的可能性,在这种情况下,他们将等待交换器; 然而,这导致不可中断的睡眠D,而不是S.
处于可中断睡眠状态的系统调用也可能被信号中断,如报警,终止,停止或继续。 然而,大多数信号会导致程序中止。 (通常)安全的两个继续忽略,不改变程序流程; 所以它会再次回到相同的条件下睡觉。
很可能,你的流程在S中的原因是他们真的在等待外部输入。 既然我们知道你的程序是加载了大量的数据,我不能告诉你发生了什么事情。
至于你如何描述你的程序:“使用file.readlines()从几个大文件中读取每个作业,然后逐行分析它们”。 这是不太可能的,这是一个有效的方法来做到这一点; 如果你只在一次扫描中逐行扫描,最好迭代文件对象(一次获取一行)。 如果您以随机顺序阅读文本行, linecache就是您的朋友。 使用mmap可以避免从磁盘缓冲区复制数据。 哪一个最适合取决于你的数据和算法的结构。
“我的大部分池塘工人的状态已经改变为S”我怀疑其他工人是有趣的。 也许睡觉的人只是在等待那些被呼出的人回来。