Подпроцесс Python: слишком много открытых файлов - программирование
Подтвердить что ты не робот

Подпроцесс Python: слишком много открытых файлов

Я использую подпроцесс для вызова другой программы и сохранения возвращаемых значений переменной. Этот процесс повторяется в цикле, и через несколько тысяч раз программа разбилась со следующей ошибкой:

Traceback (most recent call last):
  File "./extract_pcgls.py", line 96, in <module>
    SelfE.append( CalSelfEnergy(i) )
  File "./extract_pcgls.py", line 59, in CalSelfEnergy
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
  File "/usr/lib/python3.2/subprocess.py", line 745, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.2/subprocess.py", line 1166, in _execute_child
    errpipe_read, errpipe_write = _create_pipe()
OSError: [Errno 24] Too many open files

Любая идея, как решить эту проблему, очень ценится!

Код, указанный в комментариях:

cmd = "enerCHARMM.pl -parram=x,xtop=topology_modified.rtf,xpar=lipid27_modified.par,nobuildall -out vdwaals {0}".format(cmtup[1])
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
out, err = p.communicate()
4b9b3361

Ответ 1

Я думаю, проблема была в том, что я обрабатывал открытый файл с подпроцессом:

cmd = "enerCHARMM.pl -par param=x,xtop=topology_modified.rtf,xpar=lipid27_modified.par,nobuildall -out vdwaals {0}".format(cmtup[1])
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)

Здесь переменная cmd содержит имя файла, который был только что создан, но не закрыт. Затем subprocess.Popen вызывает системную команду для этого файла. После выполнения этого много раз, программа вылетала с этим сообщением об ошибке.

Таким образом, сообщение, которое я узнал из этого

Закройте файл, который вы создали, затем обработайте его

Ответ 2

В Mac OSX (El Capitan) Смотрите текущую конфигурацию:

#ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 709
virtual memory          (kbytes, -v) unlimited

Установите значение открытых файлов 10 КБ:

#ulimit -Sn 10000

Проверьте результаты:

#ulimit -a

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 10000
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 709
virtual memory          (kbytes, -v) unlimited

Ответ 3

Вы можете попытаться увеличить лимит открытых файлов ОС:

ulimit -n 2048

Ответ 4

Детский процесс, созданный Popen(), может наследовать дескрипторы открытых файлов (конечный ресурс) от родителя. Используйте close_fds=True в POSIX (по умолчанию с Python 3.2), чтобы избежать этого. Кроме того, "PEP 0446 - Сделать вновь созданные файловые дескрипторы ненаследуемыми" касается некоторых оставшихся проблем (начиная с Python 3.4).

Ответ 5

Как отмечали другие, увеличьте лимит в файле /etc/security/limits.conf, а также файловые дескрипторы были для меня лично проблемой, поэтому я сделал

sudo sysctl -w fs.file-max=100000 

И добавил строку с fs.file-max = 100000 в /etc/sysctl.conf(перезагрузка с помощью sysctl -p)

Кроме того, если вы хотите убедиться, что на ваш процесс не повлияло что-либо еще (что было у меня), используйте

cat /proc/{process id}/limits 

чтобы узнать, каковы фактические пределы вашего процесса, так как для меня программное обеспечение, использующее скрипты python, также применяло свои ограничения, которые переопределили настройки системы.

Проводя этот ответ здесь, после решения моей конкретной проблемы с этой ошибкой и, надеюсь, это поможет кому-то.

Ответ 6

Возможно, вы вызываете команду несколько раз. Если это так, каждый раз, когда вы делаете stdout=subprocess.PIPE. Между каждым вызовом попробуйте выполнить p.stdout.close().

Ответ 7

открывает файл в подпроцессе. Он блокирует вызов.

ss=subprocess.Popen(tempFileName,shell=True)
 ss.communicate()