2016-06-06 6 views
1

나는 동시 파일 객체 탐색을 허용하는 방법을 찾고있다. 주의가는 추구하는 파일의 테스트 케이스로파이썬 : 동시 파일 찾기

:

#!/usr/bin/env python2 
import time, random, os 
s = 'The quick brown fox jumps over the lazy dog' 

# create some file, just for testing 
f = open('file.txt', 'w') 
f.write(s) 
f.close() 

# the actual code... 
f = open('file.txt', 'rb') 
def fn(): 
    out = '' 
    for i in xrange(10): 
     k = random.randint(0, len(s)-1) 
     f.seek(k) 
     time.sleep(random.randint(1, 4)/10.) 
     out += s[k] + ' ' + f.read(1) + '\n' 
    return out 

import multiprocessing 
p = multiprocessing.Pool() 
n = 3 
res = [p.apply_async(fn) for _ in xrange(n)] 
for r in res: 
    print r.get() 
f.close() 

내가 read 다음, sleep 다음, 파일 내에서 임의 추구 할 작업자 프로세스를 가지고있다. 나는 그들이 실제 문자열 캐릭터 인 read을 비교합니다. 인쇄 동시성 문제를 피하기 위해 즉시 인쇄하지 않습니다.

n=1 일 때 파일 디스크립터의 동시성 때문에 일 때 모든 것이 잘못되었습니다.

def fn(): 
    fd = os.dup(f) 
    f2 = os.fdopen(fd) 

을 그리고 나는 f2를 사용

나는 fn() 내에서 파일 기술자를 복제하는 것을 시도했다. 하지만 도움이되지 않는 것 같습니다.

동시에 여러 프로세스에서 검색을 수행하려면 어떻게해야합니까? (이 경우에는 open의 파일을 fn() 안에 넣을 수는 있지만 MWE입니다. 실제로는 어렵습니다.)

답변

0

파이썬 I/O는 C의 I/O를 기반으로합니다. , C의 열린 파일 당 하나의 "현재 파일 위치"만 존재합니다. 이것은 본질적으로 공유됩니다.

수행 할 수있는 작업은 프로세스 간 잠금의 보호 아래에서 찾기 및 읽기를 수행하는 것입니다. 당신이 추구하고 읽고 싶은 때마다 다음

initializer=process_init, initargs=(multiprocessing.Lock(),) 

그 자물쇠의 보호 아래 작업을 수행합니다

def process_init(lock): 
    global seek_lock 
    seek_lock = lock 

주 과정에서

Pool 생성자이 추가

처럼 정의 :

with seek_lock: 
    f.seek(k) 
    char = f.read(1) 

모든 잠금 장치와 마찬가지로 논리적으로는 적게하고 싶습니다. 그것이 개최되는 동안 필요한. 동시 검색은 허용되지 않지만 한 프로세스의 검색이 다른 프로세스의 검색을 방해하지 못하게합니다.

물론 각 프로세스에서 파일을 열어서 각 프로세스가 파일 위치에 대한 자체 개념을 갖도록하는 것이 좋겠지 만 이미 할 수 없다고 말했을 것입니다. 다시 생각해보십시오 .--)

+0

Ah - [C'dup()'매뉴얼] (http://man7.org/linux/man-pages/man2/dup.2.html)에서 볼 수 있습니다 ... " 그들은 동일한 열린 파일 설명을 참조하므로 파일 오프셋과 파일 상태 플래그를 공유합니다. " –

+0

그때'dup()'가 얼마나 좋은지 궁금합니다. : P –

+0

다중 처리에 좋지 않음 ;-) http://stackoverflow.com/questions/11635219/dup2-dup-why-would-i-need-to-duplicate-a-file-descriptor –