ホームページ  >  記事  >  バックエンド開発  >  Pythonによるマルチプロセス制御のチュートリアル解説(例付き)

Pythonによるマルチプロセス制御のチュートリアル解説(例付き)

不言
不言転載
2018-11-15 14:00:201901ブラウズ

この記事では、Python マルチプロセス制御のチュートリアル (例付き) を紹介します。一定の参考価値があります。必要な友人は参照してください。お役に立てば幸いです。

multiprocessing の概要

Multiprocessing は、Python に付属するマルチプロセス モジュールです。大規模なバッチでプロセスを生成できます。サーバーがマルチコア CPU、スレッドモジュールに似ています。マルチプロセスは、マルチスレッドに比べて、専用のメモリ空間があるため、安定性と安全性が高く、運用や保守でバッチ操作を行う場合、マルチプロセスの方がより適用可能なシナリオが豊富です

マルチプロセスパッケージは、ローカルとリモート同時操作では、グローバル解釈ロックを持つスレッドの代わりに子プロセスを使用することが効果的に回避されるため、マルチプロセッシングはマルチコア処理を効果的に利用できます

#プロセス クラス

#Inマルチプロセスでは、プロセスは Process クラス オブジェクトを通じてバッチで生成され、start() メソッドを使用してプロセス

#1 が開始されます。 # #2.Process クラスのメソッドとオブジェクト

run()

このメソッドはプロセスの実行プロセスであり、次のことができます。サブクラスで繰り返される このメソッドを作成する場合、通常、再構築されることはほとんどありません。

start()

プロセスを開始します。各プロセス オブジェクトはこのメソッドによって呼び出される必要があります。

join([timeout])

続行する前にプロセスが終了するまで待ちます。タイムアウト期間を設定できます

name

プロセス名を取得できます。複数のプロセスが同じ名前を持つこともできます

is_alive()プロセスはまだ生きています (True または False)。プロセスの生存とは、start() の開始から子プロセスの終了までを指します

daemon

マークstart() の後のデーモン プロセスのブール値。バックグラウンドで実行するかどうかを示すためにこの値を設定します。

注: バックグラウンドでの実行が設定されている場合、バックグラウンド プログラムは実行されず、子プロセスが作成されます pid

プロセス ID

exitcode

の値を取得できます。子プロセスが終了します。プロセスが終了していない場合、値は None になります。負の値の場合は、子プロセスが終了したことを意味します

terminate()

プロセスを終了します。Windows の場合は、terminateprocess() を使用します。このメソッドは、終了して終了したプロセスを扱います。 は実行されません。

以下は簡単です。例:

multiprocessing.Process(group=None,target=None,name=None,args=(),kwargs={},*)

group: 这个参数一般为空,它只是为了兼容threading.Tread
target: 这个参数就是通过run()可调用对象的方法,默认为空,表示没有方法被调用
name: 表示进程名
args: 传给target调用方法的tuple(元组)参数
kwargs: 传给target调用方法的dict(字典)参数

もちろん各プロセスのIDを表示することもできます

#-*- coding:utf8 -*- 
import multiprocessing
import time

def work(x):
   time.sleep(1)
   print time.ctime(),'这是子进程[{0}]...'.format(x)

if __name__ == '__main__':
    for i in range(5):
        p = multiprocessing.Process(target=work,args=(i,))
        print '启动进程数:{0}'.format(i)
        p.start()
        p.deamon = True

Pythonによるマルチプロセス制御のチュートリアル解説(例付き)

ただし実際の利用プロセスでは、同時実行を完了するだけでは不十分です。たとえば、タスクが 30 個ありますが、サーバーのリソースが限られているため、毎回 5 つのタスクが同時実行されます。この場合、30 個のタスクをどのように取得するかという問題も発生します。さらに、同時処理タスク、特に時間がかかるタスクでは、一貫した実行時間を確保することが困難です。5 つのタスクが同時に実行され、そのうち 3 つは完了し、そのうちの 2 つはまだ時間がかかる場合があります。実行の場合、後続のタスクの実行を続行する前に、これら 2 つのプロセスの実行が完了するまで待つことはできません。そのため、プロセス コントロールの使用シナリオがここにあります。Process メソッドをいくつかのマルチプロセッシング パッケージおよびクラスと組み合わせて使用​​できます。

プロセス制御と通信の共通クラスPythonによるマルチプロセス制御のチュートリアル解説(例付き)

##1. キュー クラス

## は、Python に付属する Queue.Queue に似ており、主に ## で使用されます。 # 小さいキューの構文:

#-*- coding:utf8 -*- 
import multiprocessing
import time
import os

def work(x):
   time.sleep(1)
   ppid = os.getppid()
   pid  = os.getpid()
   print time.ctime(),'这是子进程[{0},父进程:{1},子进程:{2}]...'.format(x,ppid,pid)

if __name__ == '__main__':
    for i in range(5):
        p = multiprocessing.Process(target=work,args=(i,))
        print '启动进程数:{0}'.format(i)
        p.start()
        p.deamon = True
クラス メソッド: qsize()

複数のプロセスまたはスレッドがキューを消費しているため、キューのおおよそのサイズを返します。データは必ずしも正しいとは限りません

empty()

キューが空かどうかを判断し、空の場合は True を返し、そうでない場合は Falseを返します


full( )
キューがいっぱいかどうかを判断し、いっぱいの場合は True を返し、そうでない場合は Falseを返します

put(obj[, block[, timeout]])
Putオブジェクトをキューに追加し、オプションのパラメータ ブロックは True、タイムアウトは None です

#get()#オブジェクトをキューから削除します#

multiprocessing.Queue([maxsize])

二、パイプ クラス

pipe() 関数は、プロセス間でメッセージを送信できるオブジェクト接続のペアを返します。ログやプロセス制御を出力するのに役立ちます。Pip() オブジェクトは戻り値を返します。 2 つのオブジェクトです。Connection は 2 つのチャネルを表します。各接続オブジェクトには send() メソッドと recv() メソッドがあります。2 つ以上のプロセスが同時に同じパイプに対して読み取りまたは書き込みを行うため、データの混乱が生じる可能性があることに注意してください。私はテストしましたそれが、直接カバーされます。さらに、返された 2 つの接続のうち 1 つが send() データである場合、もう 1 つは、recv() でのみデータを受信できます。
#

#-*- coding:utf8 -*-
from multiprocessing import Process, Queue

def f(q):
    q.put([42,None,'hi'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print q.get()  #打印内容: [42,None,'hi']
    p.join()
出力は次のようになります。

#

三、Value,Array

在进行并发编程时,应尽量避免使用共享状态,因为多进程同时修改数据会导致数据破坏。但如果确实需要在多进程间共享数据,multiprocessing也提供了方法Value、Array

from multiprocessing import Process, Value, Array

def f(n, a):
    n.value = 3.1415927
    for i in range(len(a)):
        a[i] = -a[i]

if __name__ == '__main__':
    num = Value('d',0.0)
    arr = Array('i', range(10))

    p = Process(target=f, args=(num, arr))
    p.start()
    p.join()

    print num.value
    print arr[:]

*print
3.1415927
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]*

四、Manager进程管理模块

Manager类管理进程使用得较多,它返回对象可以操控子进程,并且支持很多类型的操作,如: list, dict, Namespace、lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value, Array,因此使用Manager基本上就够了

from multiprocessing import Process, Manager

def f(d, l):
    d[1] = '1'
    d['2'] = 2
    d[0.25] = None
    l.reverse()

if __name__ == '__main__':
    with Manager() as manager:
        d = manager.dict()
        l = manager.list(range(10))

        p = Process(target=f, args=(d, l))
        p.start()
        p.join() #等待进程结束后往下执行
        print d,'\n',l

输出:
{0.25: None, 1: '1', '2': 2}
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
可以看到,跟共享数据一样的效果,大部分管理进程的方法都集成到了Manager()模块了

五、对多进程控制的应用实例

    #-*- coding:utf8 -*-
    from multiprocessing import Process, Queue
    import time
    
    def work(pname,q):
        time.sleep(1)
        print_some = "{0}|this is process: {1}".format(time.ctime(),pname)
        print print_some
        q.put(pname)
    
    if __name__ == '__main__':
        p_manag_num = 2  # 进程并发控制数量2
        # 并发的进程名
        q_process = ['process_1','process_2','process_3','process_4','process_5']
        q_a = Queue() # 将进程名放入队列
        q_b = Queue() # 将q_a的进程名放往q_b进程,由子进程完成
    
        for i in q_process:
            q_a.put(i)
    
        p_list = [] # 完成的进程队列
        while not q_a.empty():
            if len(p_list) <p>执行结果:</p><p><img src="https://img.php.cn//upload/image/167/872/710/1542261551928622.png" title="1542261551928622.png" alt="Pythonによるマルチプロセス制御のチュートリアル解説(例付き)"></p>

以上がPythonによるマルチプロセス制御のチュートリアル解説(例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はhttps://segmentfault.com/a/1190000016855803で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。