0

파이썬 cgi에서 다중 쓰레드를 사용하여 zip 파일에 여러 개의 파일 (ard 25k)을 넣으려고합니다. 나는 아래 스크립트를 작성했지만 어떻게 든 응답은 내용 길이가 0이고 응답에 데이터가 없습니다. 파이썬에서 멀티 쓰레딩을 처음 사용했습니다. 코드에서 누락 된 것이 있습니까? 데이터가 게시되기 전에 출력물이 인쇄됩니까?파이썬에서 다중 쓰레드를 사용하여 파일 다운로드하기

도움이 될 것입니다. 동일한 코드의

b = StringIO() 
z = zipfile.ZipFile(b, 'w', zipfile.ZIP_DEFLATED) 

def read_file(link): 
    fname = link.split('/') 
    fname = fname[-1] 
    z.write(link, fname) 

if __name__ == '__main__': 
    form = cgi.FieldStorage() 
    fileLinks = form.getvalue("fileLink") 

    p = Pool(10) 
    p.map(read_file, fileLinks) 
    p.close() 
    p.join() 
    z.close() 
    zipFilename = "DataFiles-" + str(time.time()) + ".zip" 
    length = b.tell() 
    sys.stdout.write(
     HEADERS % ('application/zip', zipFilename, zipFilename, length) 
    ) 
    b.seek(0) 
    sys.stdout.write(b.read()) 
    b.close() 

순차 버전 :

for fileLink in fileLinks: 
    fname = fileLink.split('/') 
    filename = fname[-1] 
    z.write(fileLink, filename) 
z.close() 
+1

알고리즘의 단일 스레드 버전이 예상대로 작동합니까? – Apalala

+0

의견을 보내 주셔서 감사합니다. –

+0

단일 스레드로 시도하고 파일 수를 1000 개로 제한했습니다. 작동하지 않습니다. 콘텐츠 길이가 0 인 동일한 응답을 제공합니다. –

답변

1

문제는 (일반적으로 ZipFile) ZipFile.write()는 스레드로부터 안전하지 않습니다 것을해야

여기 내 코드입니다.

어떻게 든 zip 파일에 대한 스레드 액세스를 직렬화해야합니다. 어떤 잠금이 효과적으로하고있는 것은 zip 파일 생성을 직렬화하기 때문에

ziplock = threading.Lock() 

def read_file(link): 
    fname = link.split('/') 
    fname = fname[-1] 
    with ziplock: 
     z.write(link, fname) 

가 그런 식으로 일을 더 이용이 없어야합니다 : 이것은 (파이썬 3에서) 그것을 할 수있는 한 가지 방법이다.

일부 병렬화가 압축 파일에 추가하기 전에 파일의 내용을 읽고이 버전으로 달성 될 수있다 : 파일이 동일한 파일 시스템에있는 경우,

def read_file(link): 
    fname = link.split('/') 
    fname = fname[-1] 
    # the file is read in parallel 
    contents = open(link).read() 
    with ziplock: 
     # writes to the zip file a re serialized 
     z.writestr(fname, contents) 

그러나, 그 가능성이있다 읽기는 모든 효과에 대해 마치 운영 체제에 의해 직렬화 된 것처럼 작동합니다.

는 병렬화 가능한 대상이 압축되는 프로세스의 CPU 바인딩 부분이 될 것입니다, 파일이며, zip 파일처럼 동작하기 때문에 그합니다 (우편 형식으로 가능하지 않는 것 때문에 디렉토리이므로 모든 write()close()에 완전한 아카이브를 생성 할 준비가 된 상태로 남겨 두어야합니다.

다른 압축 포맷을 사용할 수있는 경우, 병렬 처리는 압축 gizp타르를 사용하여 잠금 장치없이 작업 할 (tarfile) 각 파일 읽기 및 병렬 압축 만 할 수 있기 때문에 아카이브 형식으로 타르 연속 연결이 연속적으로 수행됩니다 (.tar.gz 또는 .tgz 아카이브 형식).

+0

답변 해 주셔서 감사합니다. 당신의 도움을 주셔서 감사합니다. 나는 그것을 밖으로 시도하고 알려드립니다. –