Pythonマルチスレッド学習(中)

11384 ワード

今日はマルチスレッドを書き続けて、ここ数日ずっとマルチスレッドを読んでいますが、本の例があまりにも見苦しいので(私は生まれつき愚かかもしれませんが~~)、長い間読んでやっと分かりました.私は2冊の本を読んでやっと本の例が分かりました.だから、みんなは本を読んで勉強して分からないときは、同じ知識点の本を何冊か読んで、ネットでチュートリアルをたくさん読んで、勉強を補助することをお勧めします.
次に、ロックと条件変数について説明します.
一.[ロック](Lock)
ロックとは、プログラムの実行時に共有リソースにアクセスする必要があるマルチスレッドプログラムに対して、I/O密集型操作による結果エラーを防止することです.
ロックの使用方法:import threading
ロックの導入=threading.Lock()
ロックロックを追加します.acquire()
臨界リソースにアクセスするコード
ロックを解除release()
数値を反復出力すると、ロックをかけない場合、出力はすべて15で、ロック後は1,2,3,4.になります...13,14,15,最終出力「all done」
ロックを追加する場合、ロックを追加すると、共通リソースにアクセスできるスレッドは1つしかありません.実行時は同期実行に等しいため、実行時には速度が遅くなります.
 
コードの例:
#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-
#   
import threading
import time
from atexit import register
import random
lock = threading.Lock()
a = 0
def print_sum():
    global a
    lock.acquire()
    a += 1
    time.sleep(1)
    print(str(a))
    lock.release()
def main():
    th_list = []
    for x in range(15):
        t = threading.Thread(target=print_sum,args=())
        th_list.append(t)
    for x in th_list:
        x.start()
@register
def exit():
    print('all done')
if __name__ == '__main__':
    main()

二.じょうけんへんすう
条件変数については、判断条件を追加し、条件に合致すれば実行し、そうでなければ待機することができます.
インポートモジュールfrom threading import Condition
このモジュールにはacquirre()とrelease()があり、条件に合致しない場合に呼び出す.wait()は、スレッドがハングアップし、呼び出す.notify()または.notify_all()でスレッドをアクティブにし,条件判断を行う.
消費--生産問題で条件変数について議論する.1つの製品クラス、1つの消費者クラス、1つの生産者クラス、消費者は5つのスレッドを持っていて、生産者は1つのスレッドを持っていて、生産者は絶えず生産して、消費者は持続的に消費して、無限の生産消費が終わらない問題は存在しませんが、プログラムを停止するには手動で完成する必要があります.
コード:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import threading
import time
import random

#    ,       
#   
class Chan_pin():
    def __init__(self):
        self.count = 0
    #    
    def xiao_fei(self):
        self.count -= 1
    #    
    def sheng_chan(self):
        self.count += 1
    #        
    def pan_duan(self):
        return not self.count
    pass

#   
class Sheng_chans(threading.Thread):
    def __init__(self,tiao_jian,chan_pin):
        super().__init__()
        self.tiao_jian = tiao_jian
        self.chan_pin = chan_pin
    def run(self):
        while True:
            self.tiao_jian.acquire()
            self.chan_pin.sheng_chan()
            print('       :%s' % self.chan_pin.count)
            self.tiao_jian.notify_all()
            self.tiao_jian.release()
            time.sleep(random.random())
    pass
#     
class Xiao_fei(threading.Thread):
    def __init__(self,chan_pin,tiao_jian):
        super().__init__()
        self.tiao_jian = tiao_jian
        self.chan_pin = chan_pin
    #  run  
    def run(self):

        while True:
            self.tiao_jian.acquire()
            time.sleep(random.randint(2,5))
            if self.chan_pin.pan_duan():
                self.tiao_jian.wait()
                print('%s    ,   。。。' % threading.current_thread().name)
            else:
                self.chan_pin.xiao_fei()
                print('%s   ,     :%s' % (threading.current_thread().name,self.chan_pin.count))
                self.tiao_jian.notify_all()
                self.tiao_jian.release()
    pass

#    。
def main():
    tiao_jian = threading.Condition()
    chan_pin = Chan_pin()
    t1 = Sheng_chans(tiao_jian,chan_pin)
    t1.start()
    time.sleep(5)
    #t1.join()
    for x in range(5):
        t2 = Xiao_fei(chan_pin,tiao_jian)
        t2.start()
        print(threading.active_count())
        print(threading.enumerate())
    print(threading.enumerate()[-2].is_alive())
        #t2.join()

#  
if __name__ == '__main__':
    main()

  
三.しんごうりょう
信号量により、指定された数のスレッドを追加して共通リソースにアクセスできます.
信号量については、SemaphoreとBoundedSemaphoreの2つのモジュールが利用可能である、それぞれ2つ目のモジュールよりも1つ目のモジュールに欠点があり、1つ目は呼び出す.release()の場合、追加数が設定数を超えるとエラーが発生せず、2番目はエラーが発生します.
この文章は主に2つ目について紹介します.
このモジュールには2つの方法がある.acquire()と.release()が呼び出されています.acquire()の場合は1を減らし、0に減らすとスレッドの実行を停止し、待機に入ります.呼び出しrelease()の場合は1を追加します.
呼び出し方法:
num=5#は、5つのスレッドのみが共通リソースにアクセスできることを示します.
a = BoundedSemaphore(num)
a.acquire()
実行するコード
a.release()
 
サンプルコードは次のとおりです.
 1 #!/usr/bin/env python3.6
 2 # -*- coding: utf-8 -*-
 3 #   
 4 import threading
 5 import time
 6 from atexit import register
 7 
 8 
 9 #        ,      ,           ,      。
10 
11 num = 3
12 a = threading.BoundedSemaphore(num)
13 #           
14 def print_list(list):
15     a.acquire()
16     p = threading.current_thread().name
17     if a.acquire(False):
18         print('%s :     ' % p)
19     else:
20         print('%s:%s' % (p,list))
21     a.release()
22 
23 #     
24 class New_thread(threading.Thread):
25     def __init__(self,han_name,han_can):
26         super().__init__()
27         self.han_name = han_name #   
28         self.han_can = han_can  #        
29     def run(self):
30         self.han_name(self.han_can)
31     pass
32 
33 #
34 def main():
35     list_1 = ['aaaa', 'bbbb', 'cccc', 'dddd', 'eeee', 'ffff']
36     #    
37     thread_list = []
38     #      
39     for x in range(5):
40         t = New_thread(print_list,list_1)
41         thread_list.append(t)
42     for x in thread_list:
43         x.start()
44     #print(thread_list)
45 
46 #
47 @register
48 def exit():
49     print('all done')
50 
51 if __name__ == '__main__':
52     main()

 
以上、マルチスレッドのロック、信号量、条件変数について、間違いがあったら教えてください. 
転載先:https://www.cnblogs.com/sniper-huohuohuo/p/8854833.html