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

デッドロックはありますか?デッドロック状態には少なくとも1つのロックが必要です。今度はPythonに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()'を使ってデータを処理しているときに簡単に使うことができるので、一時変数を格納するためにGlobal変数を使うとどうなりますか? –

+0

@JafferWilson SSDを使用している場合、並列読み込み、つまりプール内で '.read()'を呼び出すことで再生することができます。しかし、これは、各作業者がファイルの読み込みを開始する場所と読み込む行の数を知る必要があるため、実装するのが非常に難しいでしょう。実装するのは簡単ではないようです。 – freakish

+0

@JafferWilson一時的なデータを保存するために、あなたは常に 'process'関数の中にローカル変数を持つことができます。例えば、 'process'呼び出しのたびにインクリメントするグローバルカウンタがある場合、問題が発生します。 'process'への呼び出しの間の状態の共有は、複数のプロセスでは機能しません。 – freakish

関連する問題