【PYTHONモジュール】threadingモジュール


threadingモジュール:CPUアイドル時間を利用してマルチタスクを実行する.Pythonのマルチスレッドは実際にIO操作に遭遇するとCPUが他のタスクに切り替わる.
1、GIL(Global Interpreter Lock):グローバル解釈器ロック
同じ時刻にCPUが1つのスレッドしか実行しないことを保証する役割を果たす.CPythonのみGILロックがあります.
 
2、簡単なthreading使用
共通クラスとメソッド名:
パラメータ
さぎょう

threading.enumerate()
リストで、すべてのアクティブなスレッド名とIDの例をリストします.
s = threading.enumerate()for v in s:    print(v.name)
threading.Tread.isAlive(スレッドインスタンス名)
スレッドインスタンス名:次のthread_create
スレッドが実行中かどうかを判断し、TrueまたはFalseを返します.
threading.Tread.isAlive(ss)またはi.isAlive()#iは作成されたThreadインスタンスです
thread_create=threading.Thread()
target:マルチスレッドを追加するオブジェクト名args:オブジェクトのパラメータ、メタグループ形式kwargs:オブジェクトの辞書パラメータname:スレッド名を指定し、デフォルトThread-N
オブジェクトをスレッドオブジェクトにインスタンス化
thread_create = threading.Tread(target=work,args=('tom',),kwargs={'work_name':'eat'})
thread_create.start()
スレッドの開始
thread_create.start()
thread_create.join()
timeout:スレッドがブロックされた時間(タイムアウト時間)timeoutデフォルト、このスレッドの実行が完了するのを待つ
スレッドが中止またはtimeoutがタイムアウトするまで待機し、プログラムの実行を続行します.
thread_create.join(5)またはthread_create.join(timeout=5)
thread_create.getName()
thread_を取得createスレッド名
thread_create.getName()
thread_create.setName()
name:スレッド名
thread_の設定createスレッド名、この名前は識別のみです
thread_create.setName('th1')
"""
     
             
"""
#   :     。

import time,random
import threading
work_list = ["  " ,"  ", "  " ,"  "]  #     
def work(name, cost):
 '''    '''
    print("     [31;2m{}[0m".format(name))
    time.sleep(cost)
    print("{}      {}  !".format(name, cost))
 
thread_list = [] #     
start_time = time.time()  #        
#     
for i in work_list:
    #        
    cost_time= random.randint(5,10)    #       ,     
    #        
    t = threading.Thread(target = work,args=(i,cost_time))
    thread_list.append(t)      #             ,    
    t.start()    #     

active_thread = threading.enumerate()    #           
print(active_thread)                     #       

for i in active_thread: 
    print (i.name)         #      name  ,     ,     Thread      self.name  ,                    
    print(i.getName())     #         
    i.setName("change-name"+i.name)    #  
    print(i.getName())     #         
    
for i in thread_list:  #           
    i.join()    #         ,           ,    
    
end_time = time.time()  #        
sum_time = end_time - start_time #      
print ('   :{}'.format(sum_time))
'''   :  Thread  run  ,   ,    __init__ run  ,       !!!!!'''
import time,random

import threading

'''  run    '''

work_list = ["  " ,"  ", "  " ,"  "] 	#     


class work(threading.Thread):

	def __init__(self,name,cost):
		threading.Thread.__init__(self)
		self.name = name
		self.cost = cost

	def run(self):
                self.do_work()	

        def do_work(self):
                """    """
 	        print("     [31;2m{}[0m".format(self.name))
		time.sleep(self.cost)
		print("{}      {}  !".format(self.name, self.cost)) 
		

start_time = time.time()		#        
thread_list = []

for i in work_list:
	cost_time = random.randint(5,9)
	t = work(i, cost_time)
	thread_list.append(t)
	t.start()

active_thread = threading.enumerate()
for i in active_thread:
        print(i.name)	#           ,  Thread-N     !!!
	
for i in thread_list:
	i.join()

end_time = time.time()		#        
sum_time = end_time - start_time	#      
print ('   :{}'.format(sum_time))

 
3、デーモンスレッドdeamon
 
クラス、メソッド、プロパティ名
パラメータ
さぎょう

setDaemon(BOOL)
BOOL:True              False
スレッドを親スレッドのデーモンスレッドとして設定するには、strar()スレッドが開始する前に設定する必要があります.
mは作成されたプロセスインスタンスです.m.setDaemon(True)
isDaemon()
なし
現在のスレッドにデーモンスレッドが設定されているかどうかを判断し、BOOL型、TrueまたはFalseを返します.
m.isDaemon()
"""    Daemon  """
import time,random
import threading
work_list = ["  " ,"  ", "  " ,"  "]  #     
def work(name, cost):
 '''    '''
 print("     [31;2m{}[0m".format(name))
 time.sleep(cost)
 print("{}      {}  !".format(name, cost))
def main_work(name):
 w = threading.Thread(target = work, args=("  ",10))
 w.start()
 w.join(9)
 
start_time = time.time()  #        
m = threading.Thread(target = main_work, args=('Done',))
m.setDaemon(True)    #       ,     ,main_work  ,main_work       
m.start()
m.join(2)
end_time = time.time()
print(" {} !!!".format("Done"))
print ("   :",end_time-start_time)
#-------------    --------------
    [31;2m  [0m
 Done !!!
   : 2.0008544921875
#--    m     ,           ,m  m               。

4、スレッドロックロック、再帰ロックRlock
ロック後、スレッドは順次実行されます.
クラス、メソッド、プロパティ名
パラメータ
さぎょう

Lock()
ロッククラス、ロックオブジェクトの作成に使用
lock = threading.Lock()
Rlock()
Rlockクラスは、再帰ロックを作成するために使用され、多重ロックと呼ばれる同じスレッドはacquire()を複数回使用できますが、同じ数のrelease()に対応する必要があります.
rlock = threading.Rlock()
acquire()
ロックとRlockの方法:ワイヤロックを有効にする
lock.acquire()
release()
ロックとRlockの方法:スレッドロックを解除する
lock.release()
###Lock  ###

import time,random
import threading
work_list = ["  " ,"  ", "  " ,"  "]  #     
def work(name,cost):
 '''    '''
 lock.acquire()    #     
 work_list[name] = name
 time.sleep(cost)
 print("time:{},list:{}".format(cost,work_list))
 lock.release()    #     ,     ,        
start_time = time.time()  #        
thread_list = []
lock = threading.Lock()
for i in range(3):
 m = threading.Thread(target = work, args=(i,3))
 thread_list.append(m)
 m.start()
for i in thread_list:
 i.join()
end_time = time.time()
print ("   :",end_time-start_time)

-----------------       ------------------
time:3,list:[0, '  ', '  ', '  ']
time:3,list:[0, 1, '  ', '  ']
time:3,list:[0, 1, 2, '  ']
   : 9.002515077590942
-----------------       ------------------
time:3,list:[0, 1, 2, '  ']
time:3,list:[0, 1, 2, '  ']
time:3,list:[0, 1, 2, '  ']
   : 3.002171516418457

5、信号量(semaphore)
 
クラス、メソッド、プロパティ名
パラメータ
さぎょう

BoundedSemaphore(num)
num:int型、num個のスレッドのみ同時実行可能
semaphoreオブジェクトの作成
semaphore = threading.BoundedSemaphore(3)
acquire()
信号量オブジェクトにスレッドを入れる
semaphore .acquire()
release()
信号量オブジェクトからスレッドを削除
semaphore .release()
   
import threading,time,random
work_list = ["  " ,"  ", "  " ,"  "]  #     
def work(name,cost):
 semaphore.acquire()
 print("{}  {}  ".format(name,cost))
 time.sleep(cost)
 #print(name)
 semaphore.release()
thread_list=[]
semaphore = threading.BoundedSemaphore(3)
index = ""
for i in work_list:
 index = index+str(work_list.index(i))
 num = random.randint(2,5)
 t = threading.Thread(target=work, args = (i+index,num))
 thread_list.append(t)
 t.start()
 
for j in thread_list:
 j.join()
 
print ("Done")

#------------  ------------
  0  2  
  01  5  
  012  4  
#       ,       ,             
  0123  2  

 
5、タイマー(Timer)
クラス、メソッド、プロパティ名
パラメータ
さぎょう

Timer(time,func,args)
time:遅延時間(単位:秒)func:実行する関数名args:パラメータ、マルチプロセス使用方法と同様
タイマインスタンスを生成し、timeの時間が長すぎるとfuncの機能を実行します.
timer=threading.Timer(3,work,('David',))

start()
スタートタイマ
timer.start()
stop()
ストップタイマ
timer.stop()
import threading
def work(name):
     print ("  :{}".format(name))
     global timer
     timer=threading.Timer(3,work,('David',))
     timer.start()
timer=threading.Timer(3,work,('David',))
timer.start()

6、イベント(Event)
Eventはスレッド同期の1つの方法であり、フラグと同様に、フラグがfalseである場合、フラグを待つすべてのスレッドがブロックされ、trueである場合、フラグを待つすべてのスレッドが起動される.
Eventは重要な概念であり,イベント駆動モデルというプログラミング思想がある.後で検討します.
 
クラス、メソッド、プロパティ名
パラメータ
さぎょう

Event()
なし
イベントオブジェクトのインスタンス化
e = threading.Event()
isSet()
なし
イベントフラグを判断し、TrueまたはFalseを返します.
e.isSet()
set()
なし
イベントフラグを設定します.isSet()はTrueです.
e.set()
clear()
なし
イベントフラグをクリアisSet()はTrue
e.clear()
wait(timeout)
timeout:時間
 
####          ####
import threading
import time


class traffic(threading.Thread):
    '''            '''
    def __init__(self,event_obj):
        threading.Thread.__init__(self)
        self.event_obj = event_obj          #       

    def light(self):
        sec = 1         #   
        while True:
            if sec / 1 == 1:                #     
                self.event_obj.set()        #       
                print ('green...')
            elif sec / 5 == 1:              #   5 ,   ,      ,         
                print ('yellow...')
            elif sec / 7 == 1:              #   7 ,   
                self.event_obj.clear()      #       
                print('red...')
            elif sec == 10:                 #  10     
                sec = 1
                continue
            sec += 1
            time.sleep(1)                   #   

    def run(self):
        #   run  ,   。
        self.light()

def car(event_obj):
    #       
    while True:
        if event_obj.isSet():               #        True,    ,    
            print('the car is running!')
        else:                               #        False,    ,    
            print('the car is stop!')
        time.sleep(1)                       #   

def exit():
    #       ,      ,C       ,    
    t = traffic(e)                                  #          
    c = threading.Thread(target=car, args=(e,))     #         
    t.setDaemon(True)                               #           ,  exit  
    c.setDaemon(True)
    t.start()                                       #     
    c.start()
    while True:                                    #         
        s = input().strip()                         #         
        if s == 'c':                               #    C,  exit
            print('    !')
            return


e = threading.Event()                       #       
ex=threading.Thread(target=exit)            #   exit    
ex.start()
ex.join()

参考資料:
https://blog.csdn.net/drdairen/article/details/60962439
https://www.cnblogs.com/wang-can/p/3582051.html
https://blog.csdn.net/wanghaoxi3000/article/details/70880753\
https://www.cnblogs.com/nulige/p/6297829.html