2013-05-13 4 views
22

서브 프로세스를 사용하여 다른 프로그램을 호출하고 리턴 값을 변수에 저장합니다. 이 과정은 루프에서 반복, 몇 천 시간 후 프로그램은 다음 오류와 함께 추락이 문제를 해결하는 방법파이썬 서브 프로세스 : 너무 많은 파일 열기

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

Communicate()가 파이프를 닫으므로 문제가되지 않습니다. 결국, 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
당신은 OS의 오픈 파일 제한 올리는 시도 할 수 있습니다

:

ulimit -n 2048

+4

실제로이 명령은'/ etc/security/limits.conf'에서 설정 한 것 이상으로 제한을 발생시키지 않습니다. 이것을 높이려면,''soft nofile 4096'' /''hard nofile 4096'과 같은 줄을 그 파일에 넣어야합니다 (여러분의 값으로'4096'을 대체하십시오). –

+1

어제이 문제로 인해서이 오류를 극복하기 위해'/ etc/security/limits.conf'와 우분투의'ulimit -n'을 통해 제한을 높여 편집해야했습니다. –

0

가 서브 프로세스에서 파일을 열 수 있습니다. 통화를 차단하고 있습니다.

맥 OSX (엘 카피 탄) 현재 구성보기에서
ss=subprocess.Popen(tempFileName,shell=True) 
ss.communicate() 
15

:

#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()으로 생성 된 하위 프로세스는 부모로부터 열린 파일 기술자 (유한 리소스)를 상속 할 수 있습니다. 피하기 위해 POSIX에서 close_fds=True을 사용하십시오 (기본값은 파이썬 3.2 이후입니다). 또한, "PEP 0446 -- Make newly created file descriptors non-inheritable" deals with some remaining issues (since Python 3.4).

다른 사람이 언급 한 것처럼
+0

적어도 모든 경우에 이것이 작동한다고 생각하지 않습니다. 1024 개의 파일 제한 (우분투 기본 설정)이있는 시스템에서 1200 개의 수면 생성 프로세스가 생성되었으며 close_fds = True 인 경우에도 문제가 발생했습니다. 그래서 나는 그것보다 더 많은 것이 있다고 생각합니다. 어쨌든 여전히 열린 프로세스에서 한도를 초과하므로 열려있는 파일 설명자를 남긴 완성 된 프로세스에 문제가 있다고 가정 할 때만 작동합니다. – Sensei

+0

@Sensei 작동합니다 : 부모 파일을 열면 (fds가 상속 가능하다는 것을 확인한 후) close_fds = False로 하위 프로세스를 생성합니다 (이전 Python 버전에서는 기본적으로 링크를 따라야 함). 얼마나 빨리 오류가 발생하는지 확인하십시오. 명백히'close_fds'는 일반적인 경우의 오류를 막을 수 없습니다 : 새로운 프로세스를 생성 할 필요조차 없습니다. – jfs

+0

그렇지 않습니다. 나는 for 루프를 돌리고 OS 제한을 맞추기에 충분한 서브 프로세스를 생성했다. close_fds = True로이 작업을 수행했습니다. 그것은 아무런 영향을 미치지 않았다. 나는 왜 틀릴 수도 있지만 내 생각에 단순히이 솔루션은 몇 개의 하위 프로세스를 생성하고 디스크립터를 정리하지 않는 경우에만 작동한다는 것입니다. 이 경우이 인수는 의미가 있지만 실제로 여러 프로세스를 생성하여 실행하려는 경우에는 작동하지 않습니다. – Sensei

2

,는 /etc/security/limits.conf에 제한을 높이고 또한 파일 기술자는 개인적으로 나에게 문제가 있었다, 그래서 나는

sudo sysctl -w fs.file-max=100000 

를하고 fs.file와 라인을 추가 - 최대 = 100000, 당신은 당신의 프로세스가 (광산이었다) 아무것도의 영향을받지 않습니다 있는지 확인하려는 경우 또한

을 (의 sysctl -p로 다시로드) /etc/sysctl.conf에 사용하는

cat /proc/{process id}/limits 

당신의 프로세스의 실제 한계가 무엇인지 나에게 알려주기 바란다. 파이썬 스크립트를 실행하는 소프트웨어에는 시스템 전체 설정을 오버라이드 한 한계가 적용되었다.

이 오류와 관련된 특정 문제를 해결 한 후이 대답을 게시하면 도움이되기를 바랍니다.

관련 문제