2

내 CPU의 단일 코어를 사용하여 파일을 처리하려고합니다. 하지만 단일 코어를 사용하는 것으로는 충분하지 않다고 생각합니다. 대신, 내 시스템의 여러 코어에 액세스 할 수 있다면 프로세스를 더 빠르고 더 빠르게 실행할 수 있습니다.다중 스레드를 사용하여 python3을 사용하여 파일 처리하기

하지만 유감스럽게도 단일 코어만을 사용하여 파일을 처리하는 것을 알고 있습니다.

data = open('datafile','r',encoding='ascii',errors='ignore') 
for line in data.readlines(): 
    splitted = line.lower().strip().split() 
    check = process(splitted[0],splitted[1]) 
    if check == '': 
     pass 
data.close() 

은 내가 별도로 line을 복용하고 원하는대로 출력을 가져 오는 동안 TEH process() 처리를위한 CPU의 전체 용량을 사용할 수있는 방법을 알고 싶어 여기에 내가 무슨 짓을? 처리 중에 쓰레드의 교착 상태를 피할 수있는 방법조차도 프로세스 출력에 위험 할 수 있습니다.

저와 함께 의견을 공유하십시오.

+0

교착 상태가 발생합니까? 교착 상태에는 적어도 하나 이상의 잠금 장치가 필요합니다. 파이썬에는 GIL이라는 것이 있기 때문에 다중 코어를 사용하는 유일한 방법은 스레드 대신 프로세스를 사용하는 것입니다. 이제는 병렬 디스크 io가 성능을 향상시킬 수도 있고 늘리지 않을 수도 있습니다 (디스크에 따라 다름). 그래서 나는'multiprocesing.Pool'을 사용하고 병렬 처리를 위해 주 프로세스에서 파일의 "청크"를 보내도록 제안합니다. – freakish

+0

@freakish 파일을 청크로 다이빙하면 느슨한 데이터가 될 수 있습니다. 원하지 않는 데이터는 전체 데이터를 유지하는 것이 중요합니다. –

+0

왜 데이터가 손실됩니까? 줄 단위로 줄을 읽고 각 줄을 자식 프로세스로 보냅니다. 여기에는 데이터 손실이 없습니다. – freakish

답변

1

우선 : 여러 코어를 활용하려면 여러 프로세스가 필요합니다. 스레드가 아닙니다. GIL로 인한 제한 사항입니다.

지금 여기에 당신이 multiprocessing.Pool 그것을 구현할 수있는 방법의 예이다 : 그것은 라인으로 파일 라인을 읽고 않습니다 그래서

from multiprocessing import Pool, cpu_count 

def process(arg1, arg2): 
    ... 

workers_count = 2*cpu_count()+1 # or whatever you need 
pool = Pool(processes=workers_count) 

with open('datafile','r',encoding='ascii',errors='ignore') as fo: 
    buffer = [] 
    for line in fo: 
     splitted = line.lower().strip().split() 
     buffer.append((splitted[0], splitted[1])) 
     if len(buffer) == workers_count: 
      results = pool.map(process, buffer) 
      buffer = [] 
      # do something with results 
    if buffer: 
     results = pool.map(process, buffer) 
     # do something with results again 

을하고 충분한 데이터를 수집 일단은 멀티 프로세스 풀을 기다립니다로 전송 병렬 처리 용. SSD가 없다면 디스크 io를 병렬로 실행하면 성능이 저하 될뿐입니다 (또한 행 단위 읽기를 병렬 처리하는 것도 간단하지 않음).

여러 프로세스를 사용하기 때문에 메모리 사이에서 메모리를 공유 할 수 없습니다. 즉, process 함수는 전역 변수를 읽거나 쓰지 않아야합니다.

+0

예 SSD가 있습니다. 'process()'를 통해 데이터를 처리하는 동안 쉽게 사용할 수 있기 때문에 전역 변수를 사용하여 임시 데이터를 저장하면 어떻게됩니까? –

+0

@JafferWilson SSD를 사용한다면 병렬 읽기, 즉 풀 내부에서'.read() '를 호출하여 재생할 수 있습니다. 그러나 각 작업자는 파일 읽기 시작 위치와 읽을 줄 수를 알아야하기 때문에 구현하기가 매우 어려울 것입니다. 구현하기 쉽지 않은 것 같습니다. – freakish

+0

@JafferWilson 임시 데이터를 저장하는 것에 대해서는 항상'process' 함수 안에 지역 변수를 넣을 수 있습니다. 맞습니까? 예를 들어 각 프로세스 호출 후에 증가하는 글로벌 카운터가있는 경우 문제가 발생합니다. '프로세스'호출 사이의 상태 공유는 여러 프로세스에서 작동하지 않습니다. – freakish

관련 문제