スレッド(スレッド)
オペレーティング・システムのスケジューラの最小単位は、命令の文字列は一組である
手順は同時にメインスレッドで開始して、新しいスレッドとメインスレッド、スレッド独立プロモーターの後にメインスレッドを起動する(サブスレッドを開始することができますスレッド)に関係なく、子供はメインスレッドの終了スレッドかどうかの実行のすべてのスレッドの終了時にシャットダウンプログラムを実行していきます
グローバルインタプリタロック(GIL)
同じ時間仕事でGIL 1つのスレッドだけデータエラーを防止するためには、スレッドの実行順序を制御することができませんが
明確な必要PythonのGILは機能ではありませんが、それが導入されたPythonのパーサ(CPythonと)で実現であるということですコンセプト、PythonはGILを頼ることはできません
スレッドモジュール
スレッドを開始
ダイレクトコール
例:
import threading
import time
def run(i): # 函数名随意
print('test', i)
time.sleep(1)
t1 = threading.Thread(target=run, args=('t1',))
t2 = threading.Thread(target=run, args=('t2',))
t3 = threading.Thread(target=run, args=('t3',))
t1.start()
t2.start()
t3.start()
threading.Thread(target=run, args=('t1',))
ターゲットは、スレッドの実行の関数で、引数が渡されたパラメータ
コールの継承
例:
import threading
class MyThread(threading.Thread):
def __init__(self, n):
super(MyThread, self).__init__()
self.n = n
def run(self): # 函数名必须是 run
print('class test', self.n)
t1 = MyThread('t1')
t2 = MyThread('t2')
t3 = MyThread('t3')
t1.start()
t2.start()
t3.start()
マルチスレッドとシングルスレッドの違い
IO操作は、CPUを取るCPU占有率を計算していない
PythonはマルチスレッドCPU集中型の操作タスクタイプに適していない、のためのタスクIO集中操作
シングルスレッドの例:
import threading
import time
def run(i):
print('test', i)
time.sleep(1)
run('t1')
run('t2')
run('t3')
そして、マルチスレッドのコントラストを見つけることができます:マルチスレッドは、印刷後に1秒待った後に終了され、単一のスレッドが各印刷後に待機しなければならないが。
他の
加わります
かかわらず、子スレッドの実行が完了したか否かを、メインスレッドが実行続けるの子スレッドを作成するためのメインスレッドは、メインスレッド及び互いの子スレッドから独立し、後の
使用は、join
メインスレッドがスレッドの実行が完了した後に子を待ち行い、その後に進むことができ
、例えば:
import threading
import time
def run(th):
print('test', th)
time.sleep(2)
start_time = time.time()
threading_list = []
num = 0
for i in range(50):
t = threading.Thread(target=run, args=('t-%s' % i,))
t.start()
threading_list.append(t)
for item in threading_list:
item.join()
print('totally', time.time() - start_time)
あなたが使用していない場合はjoin
、メインスレッドを子スレッドが作成された後、直接出力時間を継続していきます。すべてのスレッドのプログラムの実行が終了した後、2秒待って
使用してjoin
背面のメインスレッドは、すべての実行終了出力、子スレッド後の適切な時間を待つことになります
デーモンスレッド(デーモン)
デーモンスレッドがいる限り非デーモンスレッドが直接実行終了するプログラムを完了して、サービスのメインスレッドである
彼は年末までに完全に実行するために子スレッドがデーモンスレッドとして設定されている場合、プログラムが待機しません
例:
import threading
import time
def run(th):
print('test', th)
time.sleep(2)
start_time = time.time()
num = 0
for i in range(50):
t = threading.Thread(target=run, args=('t-%s' % i,))
t.setDaemon(True)
t.start()
print('totally', time.time() - start_time)
注意:setDeamon(true)
必要性start
の前に設定を
スレッドロック(ミューテックス)
次のプロセスは、複数のスレッドが各スレッドが同じデータにアクセスできることを意味し、親のメモリ空間を共有し、複数のスレッドを開始することができます。
複数のスレッドが同じデータを変更する場合は、この時点では、エラーは
:なぜ勘違いでしょうGILを持っている
があったもののGILが、データの変更を取得する処理として、一つのスレッドだけがデータを変更することはないことを確認しますエラーが発生した場合、リリースGILする前に、データを保存します
import threading
import time
def run(th):
lock.acquire() # 获取锁
global num
time.sleep(0.01)
num += 1
print('test', th)
lock.release() # 释放锁
lock = threading.Lock()
start_time = time.time()
threading_list = []
num = 0
for i in range(50):
t = threading.Thread(target=run, args=('t-%s' % i,))
t.start()
threading_list.append(t)
for item in threading_list:
item.join()
print(num)
注意:各スレッドの実行時間を長すぎない、それ以外の場合は、シリアルなり
デッドロック
ミューテックスは、デッドロックが存在するであろう存在する複数の層が存在する場合、プログラムが無限ループに入ります
import threading
def run1():
lock.acquire()
global num1
num1 += 1
lock.release()
return num1
def run2():
lock.acquire()
global num2
num2 += 1
lock.release()
return num2
def run3():
lock.acquire()
res1 = run1()
res2 = run2()
lock.release()
print(res1, res2)
num1, num2 = 0, 0
lock = threading.Lock()
for i in range(10):
t = threading.Thread(target=run3)
t.start()
while threading.active_count() != 1:
print(threading.active_count())
else:
print('-----finished-----')
print(num1, num2)
RLOCK再帰的ロック
デッドロックを回避するために、我々は、再帰的なロックを使用する必要があります RLock
import threading
def run1():
lock.acquire()
global num1
num1 += 1
lock.release()
return num1
def run2():
lock.acquire()
global num2
num2 += 1
lock.release()
return num2
def run3():
lock.acquire()
res1 = run1()
res2 = run2()
lock.release()
print(res1, res2)
num1, num2 = 0, 0
lock = threading.RLock()
for i in range(10):
t = threading.Thread(target=run3)
t.start()
while threading.active_count() != 1:
print(threading.active_count())
else:
print('-----finished-----')
print(num1, num2)
セマフォ(セマフォ)
同時にセマフォはスレッド一定数のデータ変更を許可されている間、ミューテックスは、データを変更するために一つだけのスレッドを可能にしながら、
import threading
import time
import sys
def run(th):
semaphore.acquire()
string = 'threading:' + str(th) + '\n'
sys.stdout.write(string)
time.sleep(2)
semaphore.release()
semaphore = threading.BoundedSemaphore(5) # 最多允许5个线程同时运行
for i in range(20):
t = threading.Thread(target=run, args=(i, ))
t.start()
while threading.active_count() != 1:
pass
else:
print('Done')
プログラムを実行するプロセスからわかるように:スレッドが別の5を開始した後、この5つのスレッドの最後に実行されている5つのスレッドを開始します
イベント(イベント)
イベントは、スレッド間の相互作用を可能にし、グローバル変数共感の設定
イベントを意味internal flag
二つの状態があります:True
、False
することによりset
、clear
状態を変更する、ことにより、スレッドis_set()
のイベントのステータスを取得するwait()
にFalse
時間が詰まるます
交通信号や車の対話例:
import threading
import time
event = threading.Event()
def light():
count = 0
event.set()
while 1:
if 5 < count < 10:
event.clear()
print('red')
elif count == 10:
event.set()
print('green')
count = 0
else:
print('green')
count += 1
time.sleep(1)
def car():
while 1:
if event.is_set():
print('running...')
time.sleep(1)
else:
print('waiting')
event.wait()
l1 = threading.Thread(target=light,)
l1.start()
c1 = threading.Thread(target=car,)
c1.start()