(day 29)プロセス反発ロック+スレッド

5146 ワード

目次
  • プロセス反発ロック
  • キューおよびスタック
  • プロセス間通信(IPC)
  • 生産者および消費者モデル
  • スレッド
  • スレッド
  • とは
  • スレッド
  • を使用する理由
  • スレッド
  • を開く方法
  • スレッドオブジェクトのプロパティ
  • スレッド反発ロック
  • プロセス反発ロック
    プロセス間のデータは共有されませんが、同じファイルシステムを共有します.
    反発ロック:同時をシリアルにし、実行効率を犠牲にし、データの安全を保証
  • アプリケーション:プログラムの同時実行時にデータを変更する必要がある場合に
  • を使用する.
    # data(json  )
    {"target":1}
    
    #       .py
    import json
    import time
    from multprocessing import Process
    from multprocessing import Lock
    #     
    def search(user):
        #   json      
        with open('data','r',encoding = 'utf-8')as f:
            dic = json.load(f)
            
        print(f'{user}    :{dic.get("ticket")}')
        
    def buy(user):
        #        
        with open('data','r',encoding = 'utf-8')as f:
            dic = json.load(f)        
           
        #       
        time.sleep(1)
        
        #    ,  data  
        if dic.get("ticket") > 0:
            dic['ticket'] -= 1
            with open('data','w',encoding = 'utf-8')as f:
                json.dump(dic,f)
                
        print(f'{user}    ')
        
    def run(user,mutex):
        
        
        #   :    
        search(user)
        
        #   
        mutex.acquire() 
        #   :    
        buy(user)
        #    
        mutex.release()
    
    if __name__ == '__main__':
        mutex = Lock()
        
        for i in range(10):
            p = Process(target = run,args = (f'  {i}',))
            p.start()
            
                  

    キューとスタック
  • キューはメモリ内の1つのキュー空間に相当し、複数のデータを格納することができ、「先進先出」(パイプ+ロック)
  • に従う.
  • スタックは「先進後出」
  • に従う
    from multprocessing import Queue
    
    #             
    q = Queue(3) #               ,     
    
    # q.put:    ,            
    q.put(1)
    q.put(2)
    q.put(3)
    # q.put_nowait:    ,        
    q.put_nowait(4)
    
    # q.get:       “    ”,     
    print(q.get())
    print(q.get())
    print(q.get())
    print(q.get())
    # get_nowait:    ,     ,    
    print(q.get_nowait())
    
    # q.full:        
    print(q.full())
    
    # q.empty:        
    print(q.empty:()) # False
    

    プロセス間通信(IPC)
    プロセス間データは互いに分離されており,プロセス間通信を実現するにはキューを利用することができる.
    from multiprocessing import Process
    from multiprocessing import Queue
    
    
    def test1(q):
        data = '  hello'
        q.put(data)
        print('  1          ..')
    
    
    def test2(q):
        data = q.get()
    
        print(f'  2        {data}')
    
    
    if __name__ == '__main__':
        q = Queue()
    
        p1 = Process(target=test1, args=(q, ))
        p2 = Process(target=test2, args=(q, ))
    
        p1.start()
        p2.start()
    
        print(' ')

    生産者と消費者モデル
    キューのストレージコールをバッファとして解決
    from multiprocessing import Queue, Process
    import time
    
    
    #    
    def producer(name, food, q):  #    ,   ,   
        for i in range(9):
            data = food, i
            msg = f'  {name}    {data}'
            print(msg)
            q.put(data)
            time.sleep(0.1)
    
    
    #    
    def consumer(name, q):
        while True:
            data = q.get()
            if not data:
                break
            print(f'  {name}   {data}')
    
    
    if __name__ == '__main__':
    
        q = Queue()
    
        #      
        p1 = Process(target=producer, args=('tank', '  ', q))
        p2 = Process(target=producer, args=('    ', '  ', q))
    
        #      
        c1 = Process(target=consumer, args=('egon', q))
        c2 = Process(target=consumer, args=('jason', q))
    
        p1.start()
        p2.start()
    
        c1.daemon = True
        c2.daemon = True
    
        c1.start()
        c2.start()
    
        p2.join()
        print(' ')

    スレッド
    スレッドとは
    スレッドとプロセスは仮想単位であり、何かをよりよく説明するために
    プロセス:生産資源単位
    スレッド:実行単位
    スレッドを使用する理由
    メモリリソースの節約
  • プロセスを開始
  • は名前空間を開き、プロセスを開くたびにメモリリソース
  • を占有します.
  • プロセスごとにスレッド
  • が追加されます.
  • オープンスレッド
  • 1プロセスは、複数のスレッド
  • を開くことができる.
  • スレッドのオーバーヘッドはプロセス
  • よりはるかに小さい.

    注意:スレッドは並列化できません.スレッドは並列化しかできません.プロセスは並列化できます.
    スレッドを開く方法
    from threading import Thread
    import time
    
    #       1
    def task():
        print('thread start')
        time.sleep(1)
        print('thread end')
        
    t = Thread(target = task)
    t.start()
    
    #       2
    class MyThread(Thread):
        def run(self):
            print('thread start')
            time.sleep(1)
            print('thread end')
            
    t = MyThread()
    t.start()

    スレッドオブジェクトのプロパティ
  • Threadインスタンスオブジェクトのメソッド
  • isAlive():戻りスレッドが
  • 存在するかどうか
  • getName():スレッド名
  • を返します.
  • setName:スレッド名を設定
  • threadingモジュールが提供する方法
  • currentThread().name:スレッド名
  • を返します.
  • activeCount():実行中のスレッド数
  • を返します.

    スレッド反発ロック
    スレッド間のデータ共有
    #        ,        ,                100,
    from threading import Thread, Lock
    import time
    
    mutex = Lock()
    
    n = 100
    
    
    def task(i):
        print(f'  {i}  ...')
        global n
        # mutex.acquire()
        temp = n
        time.sleep(0.1)  #     10 
        n = temp-1
        print(n)
        # mutex.release()
    
    if __name__ == '__main__':
        t_l=[]
        for i in range(100):
            t = Thread(target=task, args=(i, ))
            t_l.append(t)
            t.start()
    
        for t in t_l:
            t.join()
    
        # 100      100-1
        print(n)