Pythonマルチプロセスプログラミングの深い理解
1. Python マルチプロセス プログラミングの背景
Python のマルチプロセスの最大の利点は、マルチコア CPU のリソースを最大限に活用できることです。Python のマルチスレッドとは異なり、GIL の制限があり、マルチプロセスでのみ CPU 割り当てを実行できます。 Pythonでは、すべてに適しています。場合によっては、基本的にマルチスレッドを使用でき、その後、基本的にマルチプロセスを使用できます。
マルチプロセス プログラミングを行う場合、マルチスレッド パッケージのスレッドには、スレッドを作成し、スレッドを開始するための 3 つのメソッドがあります。実際、マルチプロセス プログラミングにはプロセス クラス Process があり、これは集中メソッドを使用して使用することもできます。マルチスレッドでは、リストなどのメモリ内のデータを直接共有できます。 -プロセスでは、メモリ データを共有できないため、共有データを処理するには別のデータ構造を使用する必要があります。マルチスレッドでは、データ共有によりデータの正確性が保証される必要がありますが、マルチプロセスではロックが発生することはほとんどありません。プロセスが共有されていないため、メモリ情報については、マルチプロセスでは、プロセス間の対話データが特別なデータ構造を通過する必要があり、主な内容は次のとおりです。
2. マルチプロセスクラス Process
マルチプロセス クラス Process とマルチスレッド クラス Thread には同様のメソッドがあります。詳細については、次のコードを参照してください。
#!/usr/bin/env python from multiprocessing import Process import os import time def func(name): print 'start a process' time.sleep(3) print 'the process parent id :',os.getppid() print 'the process id is :',os.getpid() if __name__ =='__main__': processes = [] for i in range(2): p = Process(target=func,args=(i,)) processes.append(p) for i in processes: i.start() print 'start all process' for i in processes: i.join() #pass print 'all sub process is done!'
実行する必要のある関数にはプロセスのidとpidが出力されており、親プロセスと子プロセスのid番号が確認できます。linuでは主にプロセスがforkされていて確認できます。プロセスを作成するときに、親プロセスと子プロセスの ID 番号を問い合わせます。ただし、マルチスレッドではスレッド ID が見つかりません。
start all process start a process start a process the process parent id : 8036 the process parent id : 8036 the process id is : 8037 the process id is : 8038 all sub process is done!
実行時に、join ステートメントがない場合、メイン プロセスはサブプロセスの終了を待たずに実行を継続し、サブプロセスの実行を待つことがわかります。
├─sshd(1508)─┬─sshd(2259)───bash(2261)───python(7520)─┬─python(7521) │ │ ├─python(7522) │ │ ├─python(7523) │ │ ├─python(7524) │ │ ├─python(7525) │ │ ├─python(7526) │ │ ├─python(7527) │ │ ├─python(7528) │ │ ├─python(7529) │ │ ├─python(7530) │ │ ├─python(7531) │ │ └─python(7532)
#!/usr/bin/env python import multiprocessing class MyProcess(multiprocessing.Process): def __init__(self,name,func,args): super(MyProcess,self).__init__() self.name = name self.func = func self.args = args self.res = '' def run(self): self.res = self.func(*self.args) print self.name print self.res return (self.res,'kel') def func(name): print 'start process...' return name.upper() if __name__ == '__main__': processes = [] result = [] for i in range(3): p = MyProcess('process',func,('kel',)) processes.append(p) for i in processes: i.start() for i in processes: i.join() for i in processes: result.append(i.res) for i in result: print i
プロセス間で対話する場合、最初はマルチスレッドで同じキュー構造を使用できますが、複数のプロセスではマルチプロセスでキューを使用する必要があります。コードは次のとおりです。
実際、これは上記の例を改良したもので、プロセス間でデータを交換するという目的を達成するために、主に Queue を使用してデータを保存します。
#!/usr/bin/env python import multiprocessing class MyProcess(multiprocessing.Process): def __init__(self,name,func,args): super(MyProcess,self).__init__() self.name = name self.func = func self.args = args self.res = '' def run(self): self.res = self.func(*self.args) def func(name,q): print 'start process...' q.put(name.upper()) if __name__ == '__main__': processes = [] q = multiprocessing.Queue() for i in range(3): p = MyProcess('process',func,('kel',q)) processes.append(p) for i in processes: i.start() for i in processes: i.join() while q.qsize() > 0: print q.get()
データ対話を実行するとき、親プロセスは実際にはすべての子プロセスと対話します。ただし、たとえば、各プロセスがデータを取得するためにキューに移動する場合を除き、基本的にすべての子プロセス間に対話はありません。この時点でロックを考慮する必要があります。そうしないと、データが混乱する可能性があります。
4. プロセス間の対話 Pipeパイプはプロセス間でデータを交換する場合にも使用できます。コードは次のとおりです。
上記のコードでは、Pipe で返される 2 つのソケットは主にデータの送受信に使用され、親プロセスではparent_conn が使用され、子プロセスでは child_conn がデータの送信メソッドとして使用されます。親プロセスのメソッドrecv
の送信と受信#!/usr/bin/env python import multiprocessing class MyProcess(multiprocessing.Process): def __init__(self,name,func,args): super(MyProcess,self).__init__() self.name = name self.func = func self.args = args self.res = '' def run(self): self.res = self.func(*self.args) def func(name,q): print 'start process...' child_conn.send(name.upper()) if __name__ == '__main__': processes = [] parent_conn,child_conn = multiprocessing.Pipe() for i in range(3): p = MyProcess('process',func,('kel',child_conn)) processes.append(p) for i in processes: i.start() for i in processes: i.join() for i in processes: print parent_conn.recv()
実際、複数のプロセスを使用する場合、マルチスレッドにはプールがありませんので、プールを使用するのが最も便利だと感じます。 プールを使用する場合、毎回プロセスの数を制限できます。つまり、残りのプロセスはキューに入れられ、設定された数のプロセスのみが実行されます。デフォルトでは、プロセスの数は CPU の数になります。これは multiprocessing.cpu_count() に基づく結果です。
在poo中,有两个方法,一个是map一个是imap,其实这两方法超级方便,在执行结束之后,可以得到每个进程的返回结果,但是缺点就是每次的时候,只能有一个参数,也就是在执行的函数中,最多是只有一个参数的,否则,需要使用组合参数的方法,代码如下所示:
#!/usr/bin/env python import multiprocessing def func(name): print 'start process' return name.upper() if __name__ == '__main__': p = multiprocessing.Pool(5) print p.map(func,['kel','smile']) for i in p.imap(func,['kel','smile']): print i
在使用map的时候,直接返回的一个是一个list,从而这个list也就是函数执行的结果,而在imap中,返回的是一个由结果组成的迭代器,如果需要使用多个参数的话,那么估计需要*args,从而使用参数args。
在使用apply.async的时候,可以直接使用多个参数,如下所示:
#!/usr/bin/env python import multiprocessing import time def func(name): print 'start process' time.sleep(2) return name.upper() if __name__ == '__main__': results = [] p = multiprocessing.Pool(5) for i in range(7): res = p.apply_async(func,args=('kel',)) results.append(res) for i in results: print i.get(2.1)
在进行得到各个结果的时候,注意使用了一个list来进行append,要不然在得到结果get的时候会阻塞进程,从而将多进程编程了单进程,从而使用了一个list来存放相关的结果,在进行得到get数据的时候,可以设置超时时间,也就是get(timeout=5),这种设置。
总结:
在进行多进程编程的时候,注意进程之间的交互,在执行函数之后,如何得到执行函数的结果,可以使用特殊的数据结构,例如Queue或者Pipe或者其他,在使用pool的时候,可以直接得到结果,map和imap都是直接得到一个list和可迭代对象,而apply_async得到的结果需要用一个list装起来,然后得到每个结果。
以上这篇深入理解python多进程编程就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









LinuxターミナルでPythonバージョンを表示する際の許可の問題の解決策PythonターミナルでPythonバージョンを表示しようとするとき、Pythonを入力してください...

PythonのPandasライブラリを使用する場合、異なる構造を持つ2つのデータフレーム間で列全体をコピーする方法は一般的な問題です。 2つのデータがあるとします...

10時間以内にコンピューター初心者プログラミングの基本を教える方法は?コンピューター初心者にプログラミングの知識を教えるのに10時間しかない場合、何を教えることを選びますか...

fiddlereveryversings for the-middleの測定値を使用するときに検出されないようにする方法

正規表現は、プログラミングにおけるパターンマッチングとテキスト操作のための強力なツールであり、さまざまなアプリケーションにわたるテキスト処理の効率を高めます。

UvicornはどのようにしてHTTPリクエストを継続的に聞きますか? Uvicornは、ASGIに基づく軽量のWebサーバーです。そのコア機能の1つは、HTTPリクエストを聞いて続行することです...

この記事では、numpy、pandas、matplotlib、scikit-learn、tensorflow、django、flask、and requestsなどの人気のあるPythonライブラリについて説明し、科学的コンピューティング、データ分析、視覚化、機械学習、Web開発、Hの使用について説明します。

Pythonでは、文字列を介してオブジェクトを動的に作成し、そのメソッドを呼び出す方法は?これは一般的なプログラミング要件です。特に構成または実行する必要がある場合は...
