2015-01-14 2 views
0

응용 프로그램을 실행하는 여러 개의 유닉스 서버가 있는데 응용 프로그램 로그에서 각 서버의 패턴을 grep하고 모든 서버의 grep 결과를 단일 통합 파일로 저장해야합니다.파이썬의 서브 프로세스 모듈에서 멀티 스레딩

이것은 현재 어떻게 수행하고 있는지입니다.

def run_command(command): 
    ps = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True) 
    out,err = ps.communicate() 
    if err != "": 
    return err 
    else: 
    return out 



Server_List = [['ServerA','BecomeAccountA'],['ServerB','BecomeAccountB'],['ServerC','BecomeAccountC'],['ServerD','BecomeAccountD']] 
Final_Result = "" 
path = "some/path/" 
pattern = "FindMe" 
for list in Server_List: 
    server= list[0] 
    becomeaccount = list[1] 
    command="ssh -oConnectTimeout=5 -oBatchMode=yes -l %s %s 'grep %s %s'" % (becomeaccount,server,pattern,path) 
    result = run_command(command) 
    Final_Result+=result 

with open("/some/path/output",'w') as f: 
f.write(Final_Result) 

이제 내 output 파일은 다음과 같은 내용을 포함

14012015.1449.30 [INFO] something FindMe something 
14012015.1449.40 [INFO] something FindMe something 
14012015.1450.13 [INFO] something FindMe something 
14012015.1450.48 [INFO] something FindMe something 
14012015.1451.04 [INFO] something FindMe something 
14012015.1451.19 [INFO] something FindMe something 
14012015.1451.77 [INFO] something FindMe something 
14012015.1452.09 [INFO] something FindMe something 

output 파일에서이 결과를 얻으려면, 내가 프로세스에 언젠가 소요되는 모든 서버 하나씩에 SSH 연결을해야 . 최종 출력을 얻으려면 코드에서 취한 시간을 줄여야합니다. 멀티 스레딩에서이 작업을 수행 할 수 있습니까? 한 번에 여러 ssh 연결을하는 것을 의미합니까? 나는 mutli 스레딩을 한번도 시도한 적이 없다.

참고 : - output 파일에서 라인의 순서는 중요하지 않습니다, 그래서 난 항상에서 타임 스탬프를 가지고 같은 시간 output 파일의 라인을 정렬 할 수 있기 때문에 SSH 연결의 순서는 필요하지 않습니다 각 줄의 시작.

+0

당신이하는 일이 io-bound일지도 모르는 것처럼 들리므로 멀티 스레딩 사운드가 도움이 될 수 있습니다. 그러나 모든 서버가 병렬로 모든 서버를 기다릴 수 있도록하는 것이 전부입니다. – martineau

+0

관련 없음 : 종료 상태'ps.returncode! = 0'를 오류 표시기로 사용할 수 있습니다. 'err' 문자열이 비어 있지 않은지 확인하려면'if err! = ""'('bytes'와'str'가 다른 타입 인 Python 3에서는 실패합니다)와 파이썬 2에서도 관용적이지 않습니다. – jfs

답변

1

ps.communicate()는 프로세스의 모든 출력이 읽힐 때까지 기다릴 것이라고 생각합니다. 이것은 프로그램을 순차적으로 만듭니다.

앞서 언급했듯이 각 스레드가 하나의 하위 프로세스를 호출하고 프로세스 출력/오류 읽기를 처리하는 스레드를 생성하는 것이 좋습니다.

출력을 수집 할 때는 출력을 수집 할 때 대기열 또는 병렬 액세스를 허용하는 목록에 넣어야합니다 (예 : 대기열 모듈 참조).

마지막으로 스레드에 "가입"해야합니다. 모든 쓰레드가 종료 될 때까지 기다린다.