ホームページ バックエンド開発 Python チュートリアル Pythonマルチプロセスプログラミングの深い理解

Pythonマルチプロセスプログラミングの深い理解

Jun 16, 2016 am 08:47 AM

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!'
ログイン後にコピー
上記の例でわかるように、マルチプロセスとマルチスレッドの API インターフェイスは同じです。これは、プロセスの作成、実行の開始、プロセスの完了を待つ参加を示しています。終わり。

実行する必要のある関数にはプロセスのidとpidが出力されており、親プロセスと子プロセスのid番号が確認できます。linuでは主にプロセスがforkされていて確認できます。プロセスを作成するときに、親プロセスと子プロセスの ID 番号を問い合わせます。ただし、マルチスレッドではスレッド ID が見つかりません。

オペレーティング システムで ID をクエリする場合は、pstree を使用してクリアするのが最善です:
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
ログイン後にコピー

3. プロセス間のインタラクション キュー

プロセス間で対話する場合、最初はマルチスレッドで同じキュー構造を使用できますが、複数のプロセスではマルチプロセスでキューを使用する必要があります。コードは次のとおりです。

実際、これは上記の例を改良したもので、プロセス間でデータを交換するという目的を達成するために、主に 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()
ログイン後にコピー
Queueを使う場合、実際にソケットを使うのはsendを送信してrecvを受信するだけなので、という感じです。

データ対話を実行するとき、親プロセスは実際にはすべての子プロセスと対話します。ただし、たとえば、各プロセスがデータを取得するためにキューに移動する場合を除き、基本的にすべての子プロセス間に対話はありません。この時点でロックを考慮する必要があります。そうしないと、データが混乱する可能性があります。

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()
ログイン後にコピー

5. プロセスプール pool

実際、複数のプロセスを使用する場合、マルチスレッドにはプールがありませんので、プールを使用するのが最も便利だと感じます。 プールを使用する場合、毎回プロセスの数を制限できます。つまり、残りのプロセスはキューに入れられ、設定された数のプロセスのみが実行されます。デフォルトでは、プロセスの数は 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多进程编程就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

LinuxターミナルでPythonバージョンを表示するときに発生する権限の問題を解決する方法は? LinuxターミナルでPythonバージョンを表示するときに発生する権限の問題を解決する方法は? Apr 01, 2025 pm 05:09 PM

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

あるデータフレームの列全体を、Python内の異なる構造を持つ別のデータフレームに効率的にコピーする方法は? あるデータフレームの列全体を、Python内の異なる構造を持つ別のデータフレームに効率的にコピーする方法は? Apr 01, 2025 pm 11:15 PM

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

プロジェクトの基本と問題駆動型の方法で10時間以内にコンピューター初心者プログラミングの基本を教える方法は? プロジェクトの基本と問題駆動型の方法で10時間以内にコンピューター初心者プログラミングの基本を教える方法は? Apr 02, 2025 am 07:18 AM

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

中間の読書にどこでもfiddlerを使用するときにブラウザによって検出されないようにするにはどうすればよいですか? 中間の読書にどこでもfiddlerを使用するときにブラウザによって検出されないようにするにはどうすればよいですか? Apr 02, 2025 am 07:15 AM

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

正規表現とは何ですか? 正規表現とは何ですか? Mar 20, 2025 pm 06:25 PM

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

uvicornは、serving_forever()なしでhttpリクエストをどのように継続的に聞いていますか? uvicornは、serving_forever()なしでhttpリクエストをどのように継続的に聞いていますか? Apr 01, 2025 pm 10:51 PM

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

人気のあるPythonライブラリとその用途は何ですか? 人気のあるPythonライブラリとその用途は何ですか? Mar 21, 2025 pm 06:46 PM

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

文字列を介してオブジェクトを動的に作成し、Pythonでメソッドを呼び出す方法は? 文字列を介してオブジェクトを動的に作成し、Pythonでメソッドを呼び出す方法は? Apr 01, 2025 pm 11:18 PM

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

See all articles