2011-10-08 4 views
4

아래 코드는 업로드 된 그림을 다른 곳과 동기화하는 데 사용됩니다. 작동하지만 일정 기간 (약 10 일) 후에 서비스는 사용할 수 없으며 'filedescriptor가 select()에서 범위를 벗어났습니다.'라는 오류가 표시되지만 서비스를 다시 시작하면 문제가 해결됩니다.rsync로 파이썬의 서브 프로세스를 사용할 때 "select()"에서 filedescriptor를 벗어났습니다

# sync.py 

def sync_file(source_pic, hashval, retry_num=3): 

    pic_path = os.path.join(gen_dir(hashval), os.path.split(source_pic)[1]) 
    filename = tempfile.mkstemp()[1] 
    with open(filename, 'w') as f: 
     f.write(pic_path) 

    for sync_path in options.sync_paths: 
     try_num = 0 
     rsync_cmd = ['rsync','-au', '--files-from='+filename, options.pic_path, sync_path] 

     while try_num < retry_num: 
      proc = subprocess.Popen(rsync_cmd,stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
      stdout_value, stderr_value = proc.communicate() 

      if len(stderr_value) != 0: 
       logger.error('sync failed: %s' % stderr_value) 
       try_num = try_num + 1 
       #raise UploadException('sync failed') 
      else: 
       break 

    os.remove(filename) 

로그 정보 :

File "/path/to/sync.py", line 25, in sync_file 
    stdout_value, stderr_value = proc.communicate() 
File "/usr/lib/python2.6/subprocess.py", line 691, in communicate 
    return self._communicate(input) 
File "/usr/lib/python2.6/subprocess.py", line 1211, in _communicate 
    rlist, wlist, xlist = select.select(read_set, write_set, []) 
    ValueError: filedescriptor out of range in select() 

이 오류의 원인이 닫히지 않은 파일 설명입니까? 그것은 서브 프로세스가 파일 디스크립터를 닫지 않는 것처럼 보입니다. 1024 번 실행될 때 파일 디스크립터가 범위를 벗어납니다. (우리는 파이썬 2.6을 사용하고 있고, 서브 프로세스는 select.select()를 사용하도록 강제되어 있습니다.이 파일에는 epoll이 가능하더라도 1024 개의 파일 디스크립터가 있습니다)

+0

마침내 나는 Popen이 PIPE 리디렉션을 제거하고'proc.returnval'을 확인하면 작동하는 것처럼 보입니다. – limboy

답변

2

파일 디스크립터를 수동으로 닫을 수 있습니다. communicate으로 전화 한 후 proc.stderr.close()proc.stdout.close()으로 전화하십시오.

+2

실제로 문제가 해결 되었습니까? '서브 프로세스 '의 소스를 살펴 보았고'_communicate'에서 자동으로 디스크립터를 닫아야하는 것처럼 보입니다. –

+0

나는 그들이 동의해야한다. 그러나 당신의 경우에 어떤 이유로 그들은 그렇지 않습니다. –

+0

귀하의 조언에 감사드립니다, 나는 그것을 시도하고 그것이 작동하는지 확인합니다. – limboy

0

https://bugzilla.redhat.com/show_bug.cgi?id=609020

Prior to Python 2.7, programs that used ulimit -n to enable communication with large numbers of subprocesses could still monitor only 1024 file descriptors at a time, which caused an exception:

ValueError: filedescriptor out of range in select() 

This was due to the subprocess module using the select system call. The module now uses the poll system call, removing this limitation.

가능한 수정 : 사용 파이썬 2.7 이상, 또는 poll를 사용하여 코드를 백 포트.

관련 문제