2013-05-13 2 views
22

Я использую подпроцесс для вызова другой программы и сохранения возвращаемых значений переменной. Этот процесс повторяется в цикле, и через несколько тысяч раз программа разбился со следующей ошибкой:Подпроцесс 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() 
+1

Общайтесь() закрывает трубу, так что это не ваша проблема. В конце концов, Popen() - это просто команда, которая выполняется, когда вы заканчиваете работу с трубами ... проблема может быть в другом месте вашего кода, при этом остальные файлы остаются открытыми. Я заметил «SelfE.append» ... вы открываете другие файлы и сохраняете их в списке? – tdelaney

ответ

10

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

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 varia ble, имя файла, который только что был создан, но не закрыт. Затем subprocess.Popen вызывает системную команду в этом файле. После этого много раз, программа потерпела крах с этим сообщением об ошибке.

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

Close the file you have created, then process it

Благодаря

3

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

ulimit -n 2048

+4

Фактически эта команда не повысит предел выше того, что было установлено в '/ etc/security/limits.conf'. Чтобы поднять его, вам нужно поместить такие строки, как этот '* soft nofile 4096' /' * hard nofile 4096' в этот файл (замените '4096' своим собственным значением). –

+1

Раньше в эту проблему вчера, и мне пришлось отредактировать «/ etc/security/limits.conf» И повысить лимит через 'ulimit -n' в ubuntu, чтобы преодолеть эту ошибку. –

0

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

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

В 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 

Набор открытых файлов значение до 10K:

#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 
4

Детский процесс, созданный Popen(), может наследовать дескрипторы открытых файлов (конечный ресурс) от родителя. Используйте close_fds=True на POSIX (по умолчанию с Python 3.2), чтобы избежать этого. Также, "PEP 0446 -- Make newly created file descriptors non-inheritable" deals with some remaining issues (since Python 3.4).

+0

Я не думаю, что это работает, по крайней мере во всех случаях. Я создал 1200 нерешенных процессов сна в системе с ограничением на 1024 файла (по умолчанию на Ubuntu), и он взорвался даже с помощью close_fds = True. Поэтому я думаю, что есть нечто большее, чем это. Поскольку у вас все еще есть предел в открытых процессах, и это работает, только если вы предполагаете, что проблема заключается в законченных процессах, которые оставили дескрипторы открытых файлов. – Sensei

+0

@Sensei: он работает: открывайте файлы в родительском (убедитесь, что fds наследуются), затем подпроцессы появляются с помощью 'close_fds = False' (оба значения по умолчанию для старых версий Python, следуйте ссылкам). Посмотрите, как скоро вы получите сообщение об ошибке. Очевидно, что 'close_fds' не может предотвратить ошибку в общем случае: вам даже не нужно создавать новый процесс, чтобы получить его. – jfs

+0

Кроме того, что это не так. Я запускал простой цикл и генерировал достаточно подпроцессов для достижения предела ОС. Я сделал это с помощью close_fds = True. Это не повлияло. Возможно, я ошибаюсь в том, почему, но я предполагаю, что это решение работает только в том случае, если вы создаете несколько подпроцессов и никогда не очищаете дескрипторы. В этом случае этот аргумент имеет смысл, но я не вижу его работоспособным, если вы на самом деле намерены порождать и запускать сразу несколько процессов. – Sensei

2

Как уже отмечалось, повышают предел в /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, также применяло свои ограничения, которые переопределили настройки системы.

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

Смежные вопросы