python学習の道-プロセス-day 09

11444 ワード

アウトライン:1.なぜマルチプロセスが必要なのか2.マルチプロセス作成3.プロセスを利用してパイプ通信を実現する.マルチプロセス情報共有5.プロセスロック6.プロセスプール7.列1Pythonはマルチスレッドがある以上、なぜマルチプロセスを使用するのですか?Pythonのマルチスレッド(各cpuは同じ時間に1つのスレッドしか実行できません.Pythonのマルチスレッドはコンテキストの切り替えにすぎません.cpuの速度が非常に速いので、切り替えを感じることはできません.つまりpythonのマルチスレッドはマルチタスクの並列ではありません)pythonはデータの安全を保証するために(同じデータが同じ時間に同じスレッドでしか変更できないことを確認する)ため、コードを実行するたびにグローバル解釈器ロックGILを取得する必要があります.(global interpreter lock)GILの存在は1つのプロセス内で同じ時間に1つのスレッドしか同時に実行できないことが多く,マルチコア上のCPUの効率が大幅に低下した.python下のマルチスレッドはCPU密集型コードに対して効率が低いため,マルチプロセスを導入した.pythonのマルチスレッドはIO密集型コード(ファイル処理、ネットワーク爬虫類など)に優れています.二.マルチプロセス作成
import multiprocessing
from multiprocessing import process
import time,os
def run(name):
    time.sleep(2)
    print("%s in run id %s"%(name,os.getpid()))

if __name__=="__main__":
    for i in range(3):
      p=multiprocessing.Process(target=run,args=("%s"%i,))
      p.start()
#  :0 in run id 12188
#      1 in run id 12700
#      2 in run id 13608

三.プロセスによるパイプ通信の実現
#import multiprocessing
from multiprocessing import Process,Pipe#pipe   
def run(conn):
   conn.send("hello")#        
   print("from parent information:",conn.recv())#        
   conn.close()
if __name__=="__main__":
    parent_pipe,child_pipe=Pipe()#              ,       
    p=Process(target=run,args=(child_pipe,))#         
    p.start()#         
    print( parent_pipe.recv())#      
    parent_pipe.send("how are you")#        
    p.join()#     ,                 ,          
    print("process over...")
#    :hello
#          from parent information: how are you
#          process over..
#  join      hello
#                    process over...
#                    from parent information: how are you

四.複数のプロセス間の情報共有を実現し、同じデータ(リスト、辞書、ロック、変数、信号、イベント)を共同で操作します.–Manager()
import  multiprocessing
from multiprocessing import managers,process
import os
def run(d,l):
    d[1]="hello"
    d[2]="jack"
    l.append(os.getpid())
    print(l)
if __name__=="__main__":
        man=multiprocessing.Manager()
        d=man.dict()#                    
        l=man.list()#      
        obj=[]#     
        for i in range(9):
            p=multiprocessing.Process(target=run,args=(d,l))#  d,l  
            p.start()
            obj.append(p)
        for t in obj:
            t.join()
        print(d)
        print(l)
# [6780]
# [6780, 6744]
# [6780, 6744, 9120]
# [6780, 6744, 9120, 15304]
# [6780, 6744, 9120, 15304, 14320]
# [6780, 6744, 9120, 15304, 14320, 3596]
# [6780, 6744, 9120, 15304, 14320, 3596, 17252]
# [6780, 6744, 9120, 15304, 14320, 3596, 17252, 16988]
# [6780, 6744, 9120, 15304, 14320, 3596, 17252, 16988, 17212]
# {1: 'hello', 2: 'jack'}
# [6780, 6744, 9120, 15304, 14320, 3596, 17252, 16988, 17212]

五.プロセスロックプロセスのデータは独立しているのに、なぜロックを追加しますか?出力画面の共有により、制御出力の乱れを防止するため
import multiprocessing
from multiprocessing import Process, Lock
def f(l,i):
    l.acquire()
    print("hello world",i)
    l.release()

if __name__=="__main__":
    lock=Lock()
    for num in range(10):
        Process(target=f,args=(lock,num)).start()

六.プロセスプール(pool)の役割:同じ時間にcpu上で実行するプロセスの個数を制限します大量のサブプロセスを起動する場合、プロセスプールの方式で大量にサブプロセスを作成してこのコードを実行することができます時私のCPUの占有率は99%に達して、ハングアップをもたらします
import time
from multiprocessing import Process, Pool
def foo(num):
    time.sleep(2)
    return num*2
#__name__       ,              __main__ 。        ,
#          ,         ,        ,       
pool=Pool(5)#       5   ,         
for i in range(5):
    pool.apply_async(func=foo,args=("t-%s"%i,))
         #apply----  ,      apply_async------  ,  
print("working---------")
pool.close()
pool.join()#      join!!!!
print("process end")
#              ,    ,      

七.キュー(Queue)1.キューの操作方法
import queue
#1.      
q = queue.Queue(maxsize = 10)#maxsize       。  maxsize  1         
#2.        
#put(self, item, block=True, timeout=None) item     ,
q.put()
#3.            
q.get()
q.qsize() #       
q.empty() #      ,  True,  False
q.full() #      ,  True,  False
q.full #  maxsize     
q.get([block[, timeout]]) #    ,timeout    
q.get_nowait() #  q.get(False)
q.put(item) #    ,timeout    
q.put_nowait(item) #  q.put(item, False)
q.task_done() #         ,q.task_done()                   
q.join() #            ,       

2.生産者と消費者スレッドとの間の情報伝達のための、マルチスレッドプログラミングに適した先進的な先行データ構造、すなわちキューを提供する.FIFOキュー–先進先出
import queue
q=queue.Queue()
for i in range(10):
    q.put(i)
while q is not None:
    print(q.get())#  0-9

LIFOキュー–後進先出q=queue.LifoQueue()優先キューq=queue.PriorityQueue() 3.キューインスタンス分析、生産者消費者モデル
import queue,time,threading
#                  
#                      
q=queue.Queue(maxsize=10)
def product(name):
    count=1
    while True:
        q.put("  %s"%count)
        print("     num:",count)
        count+=1
def custom(name):
    while True:
        print("%s  %s   ..."%(name,q.get()))
        time.sleep(0.1)
p=threading.Thread(target=product,args=("jack",))
p.start()
c=threading.Thread(target=custom,args=("rose",))
c.start()