2014-02-27 2 views
0

제가 틀렸을 경우 제발 저를 시정하십시오. 목표 : 다른 프로세스로 생성하여 파일을 복사합니다 (실제 복사는 호출 프로세스를 "잠금"하지 않습니다).파이썬 : 서브 프로세스를 사용하여 파일 복사

cmd = ['cp', '/Users/username/Pictures/2Gb_ImageFile.tif', '/Volume/HugeNetworkDrive/VerySlow/Network/Connection/Destination.tif'] 

def copyWithSubprocess(cmd):   
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

copyWithSubprocess(cmd) 
+1

프로세스를 "잠금"한다는 것은 무엇을 의미합니까? 이것은 하위 프로세스가 종료 될 때까지 계속 대기합니다. (편집 : 질문이 편집되었습니다;이 의견은 "의사 소통"통화가 포함되어있을 때 더 의미가 있습니다) –

+0

뭐가 문제입니까? ... 서브 프로세스는'comunnicate' 또는 다른 메소드를 호출 할 때까지 차단해서는 안됩니다 ... –

+0

@JeremyRoman 왜 서브 프로세스가 끝날 때까지 기다릴까요? (Im은 거의 긍정적이며 산란 후 즉시 실행되지 않습니다.) –

답변

1

Popen(cmd, stdout=PIPE, stderr=PIPE) 이 부모 프로세스를 "잠금"하지 않습니다 [편집 스레딩에 대한 제거 가짜 조언과 덜 과장으로 제 주장을했다].

cmd은 전체 파이프 버퍼로 인해 충분한 출력을 생성 할 경우 자체적으로 작동을 멈출 수 있습니다. 당신이 하위 프로세스 '출력을 폐기 할 경우 DEVNULL 대신 PIPE의 사용

import os 
from subprocess import Popen, STDOUT 

DEVNULL = open(os.devnull, 'wb') #NOTE: it is already defined in Python 3.3+ 
p = Popen(cmd, stdout=DEVNULL, stderr=STDOUT) 
# ... 

당신이 다음 몇 가지 방법 사용할 수있는 메인 스레드를 차단하지 않고 출력을 처리 할 경우 : IOCP와 fcntl, select, 명명 된 파이프를, threads. 후자는 더 휴대용 방법 :

p = Popen(cmd, stdout=PIPE, stderr=PIPE, bufsize=-1) 
bind(p.stdout, stdout_callback) 
bind(p.stderr, stderr_callback) 
# ... 

bind() 기능 :

import shutil 
from threading import Thread 

Thread(target=shutil.copy, args=['source-file', 'destination']).start() 
:

from contextlib import closing 
from functools import partial 
from threading import Thread 

def bind(pipe, callback, chunksize=8192): 
    def consume(): 
     with closing(pipe): 
      for chunk in iter(partial(pipe.read, chunksize), b''): 
       callback(chunk) 
    t = Thread(target=consume) 
    t.daemon = True 
    t.start() 
    return t 

당신은 메인 스레드를 차단하지 않고 파이썬에서 파일을 복사하는 외부 프로세스가 필요하지 않습니다

파이썬은 I/O 중에 GIL을 릴리즈 할 수 있으므로 복사는 메인 스레드와 동시에 그리고 병렬로 발생합니다.

여러 프로세스를 사용하는 스크립트를 비교할 수 :

import shutil 
from multiprocessing import Process 

Process(target=shutil.copy, args=['source-file', 'destination']).start() 

을 당신이 당신의 프로그램이 다음 사망 Truethread_or_process.daemon 속성을 설정할 때 복사를 취소하십시오.

+0

bind()에 대한 인수로 'stdout_callback'및 'stderr_callback' function .... bind (p.stdout, stdout_callback) 및 bind (p.stderr, stderr_callback)입니다. 가능하다면 우리가 얻은 변수가 어디에 있는지 분명히 밝혀주십시오. 미리 감사드립니다. – alphanumeric

+0

@Sputnix : 서브 프로세스의 stdout/stderr를 처리하는 것은 여러분의 함수입니다. 코드에서'콜백 (청크)'을 보시겠습니까? 예 :'def stdout_callback (chunk) : print ("stdout"% len (chunk))에 % d 바이트를 얻었습니다. " – jfs

+0

이 페이지의 하단에 내가 게시 한 코드를보십시오 ... 코드입니다 나는 도망 간다. 그것은 내게 오류가 발생합니다 : "NameError : 글로벌 이름 'stdout_callback'정의되지 않았습니다" – alphanumeric

1

파이썬으로 복잡한 비동기 프로세스를 처리하는 가장 쉬운 방법은 같은 작업을 지원하기 위해 특별히 설계와 밀접하게 threading 모듈 (실제로 내가 작성한 코드의 평행 인터페이스를 가지고 있던 multiprocessing 라이브러리를 사용하는 것입니다 이는 하나의 라이브러리 또는 다른 라이브러리를 가져 와서 멀티 스레딩과 멀티 프로세싱 작업 사이를 전환 할 수 있지만 모듈의 어느 부분을 활용했는지에 대해서는 상당히 엄격한 제한이 필요했습니다.

:

+0

여러 파일을 복사 할 때 다중 프로세스를 하위 프로세스와 함께 사용하는 방법을 살펴 보는 것이 흥미로울 것입니다. 서브 프로세스와 함께 사용할 경우 다중 처리의 간단한 예제를 게시 하시겠습니까? 나는 multy-processing/multy-threated하게 modieded 될 수있는 아래의 간단한 코드를 게시하고 있습니다.간단한 예가 더 충분합니다. – alphanumeric

+0

'Popen'은 "비동기식"입니다. 이것은 파이썬에서 외부 프로세스를 호출하는 방법입니다. – jfs

+0

파이썬에서 비동기 프로세스를 호출하는 방법 중 하나입니다. 귀하의 알림을 감안할 때, 나는 내 대답의 두 번째 부분을 제거하고 첫 번째 부분을 수정합니다. picklable Python 객체를 서브 프로세스와 통신 할 수 있기를 원한다면, 서브 프로세스 모듈은 쉘을 처리하는 것과 같은 종류의 프로세스 상호 작용을 모방하도록 설계되었습니다. [서브 프로세스와 멀티 프로세스의 차이점에 대한 나의 이해를 더하기 위해 편집 됨] – holdenweb