Python毎日メモ13


今回の内容:スレッド
>>Python毎日メモ-カタログ<<
スレッド
マルチスレッドの使用
  • Thread()group:スレッドグループ、現在はNone target:実行するターゲットタスク名*args:実行タスクにメタグループでパラメータを渡す**kwargs:辞書でパラメータを渡すname:スレッド名、一般的に
  • を設定しない
    #       
    import threading
    import time
    def sing():
        #       current_thread()
        current_thread = threading.current_thread()
        print("sing:", current_thread)
        #   sleep     10        
        for i in range(5):
            print("   。。。")
            time.sleep(0.5)
    
    def dance():
        #       
        current_thread = threading.current_thread()
        print("dance:", current_thread)
        #   sleep     10        
        for i in range(3):
            print("   。。。")
            time.sleep(0.7)
    
    #     
    #sing()  # sing: <_mainthread started=""/>
    
    if __name__ == '__main__':
        #       
        current_thread = threading.current_thread()
        print("main_thread",current_thread) # main_thread <_mainthread started=""/>
        #      ,    sing() dance()  
        sing_thread = threading.Thread(target=sing, name="sing_thread")
        dance_thread = threading.Thread(target=dance, name="dance_thread")
    
        #     
        #         ,       
        sing_thread.start()
        dance_thread.start()
    

    スレッドパラメータ
  • は要素の方式でパラメータを伝達し、要素の中の要素の順序とパラメータのパラメータの順序は一致している
  • を維持する.
  • 辞書の形式で参照を行い、辞書の中のkeyと関数パラメータの名前が一致することを保証する
  • import threading
    def show_info(name, age):
        print("name:%s age%d" % (name, age))
    
    if __name__ == '__main__':
        '''
            1、          ,                     
            2、          ,       key         
        '''
        sub_thread = threading.Thread(target=show_info, args=('  ', 30))
        sub_thread.start()
    
        sub_thread = threading.Thread(target=show_info, kwargs={
         'name': "  ", 'age': 20})
        sub_thread.start()
    

    スレッドの別の作成方法_thread
    import _thread
    import time
    #          
    def print_time(thread_name, delay):
        count = 0
        while count < 5:
            time.sleep(delay)
            count += 1
            print("%s:%s"%(thread_name,time.ctime(time.time())))
    
    #       
    try:
        _thread.start_new_thread(print_time, ("Thread-1", 2))
        _thread.start_new_thread(print_time, ("Thread-2", 4))
    except:
        print("Error:      ")
    while 1:
        pass
    

    start()起動スレッド
  • threadingモジュールを使用してスレッドを作成し、threadingを使用することができます.
  • Threadは、スレッドを作成するサブクラスを継承し、インスタンス化後にstart()メソッド起動方法
  • を呼び出す.
    import threading
    import time
    
    exitFlag = 0    #          
    class my_thread(threading.Thread):
        def __init__(self, threadID, name, counter):
            threading.Thread.__init__(self)
            self.threadID = threadID
            self.name = name
            self.counter = counter
        def run(self):  #       run  
            print("    :"+ self.name)
            print_time(self.name, self.counter, 5)
            print("    :"+self.name)
    
    # self.counter  delay(    )     counter = 5
    def print_time(thread_name, delay, counter):
        while counter:
            if exitFlag:
                thread_name.exit()
            time.sleep(delay)
            print("%s:%s"%(thread_name,time.ctime(time.time())))
            counter -= 1
    
    #      
    thread1 = my_thread(1, 'Thread-1', 1)
    thread2 = my_thread(2, 'Thread-2', 2)
    thread1.start() #     run     !!
    thread2.start()
    

    デーモンスレッド
  • メインスレッドはサブスレッドが終了してから終了するのを待っています.サブスレッドを終了したくない場合はどうしますか?
  • 解決方法:サブスレッドをデーモンスレッドに変更すればよい(setDaemon(true))
  • import threading
    import time
    def task():
        for i in range(5):
            print("     。。。%d" % i)
            time.sleep(0.5)
    
    if __name__ == '__main__':
        '''       '''
        sub_thread = threading.Thread(target=task)
        sub_thread.setDaemon(True)  #            
        sub_thread.start()  #     
        time.sleep(1)
        print("over")
    
    

    スレッド共有グローバル変数
    join():スレッドが終了するまでスレッドにリソースを占有させる
    import threading
    import time
    #         
    g_list = []
    #        
    def add_data():
        for i in range(3):
            g_list.append(i)
            print("add:",i)
            time.sleep(0.3)
        print("      ", g_list)
    #        
    def read_data():
        print("read:", g_list)
    
    if __name__ == '__main__':
        #           
        add_thread = threading.Thread(target=add_data)
        read_thread = threading.Thread(target=read_data)
    
        add_thread.start()
        #      (   )              ,       
        add_thread.join()
        read_thread.start()
    

    マルチスレッドグローバル変数のケース
    マルチスレッド操作のグローバル変数の問題:
  • 変数num
  • を作成
  • の最初のスレッドが実行するとnumの値は10000(1単位ずつ)
  • に増加する.
  • の2番目のスレッドの実行が完了するとnumの値は20000(1単位ずつ)
  • に増加する.
    import threading
    import time
    num = 0
    
    def add1():
        global num
        for i in range(10000):
            num += 1
            # time.sleep(0.0001)        
            print("num:", num)
        print("----num----", num)
    
    if __name__ == '__main__':
        add1_thread = threading.Thread(target=add1)
        add2_thread = threading.Thread(target=add1)
        add1_thread.start()
        add1_thread.join()
        add2_thread.start()
    

    ワイヤロック
    ロックの作成:lock=threading.ロック()ロック:lock.acquire()反発ロック:
  • は、1つの期間に1つのスレッドだけがコードを実行することを保証することができ、グローバル変数のデータに問題がないことを保証することができる
  • .
  • スレッド待ちと反発は、複数のタスクを単一のタスクに変更して実行します.
  • の利点は、データの正確性を保証できることであるが、実行する性能は
  • 低下する.
    ケース1:
    ケースでは、task 1でロックが使用され、task 1スレッドがリソースを独占できるようになり、task 2はtask 1が終了してから実行を開始する必要がある.
    import threading
    g_num = 0
    #        
    lock = threading.Lock() # Lock()        ,                  
    #       ,  100    
    def task1():
        #   
        lock.acquire()
        for i in range(10):
            global g_num
            g_num += 1
            print("task1=", g_num)
        #       
        # print("task1=", g_num)
    
    
    def task2():
        for i in range(10):
            global g_num
            g_num -= 1
            print("task2=", g_num)
        #       
        # print("task2=", g_num)
    
    if __name__ == '__main__':
        #        
        oneThread = threading.Thread(target=task1)
        twoThread = threading.Thread(target=task2)
        #         ,           ,       
        oneThread.start()
        twoThread.start()
        #     :        ,task1           task2   
    

    ケース2:
    import threading
    #      
    lock = threading.Lock()
    def get_value(index):
        #   
        lock.acquire()
        my_list = [4, 6, 8]
        #         
        if index >= len(my_list):
            print("    ", index)
            #      ,      
            lock.release()
            return
        #        
        value = my_list[index]
        print(value)
        #      ,     value,       
        #    ,       value
        lock.release()
    if __name__ == '__main__':
        for i in range(10):
            #              
            sub_thread = threading.Thread(target=get_value,args=(i,))
            sub_thread.start()
    

    もしこの文章があなたに役に立つなら、いいねをつけましょう.