(day 30)GIL+スレッドに関する知識点
7221 ワード
目次昨日の内容 プロセス反発ロック キュー プロセス間通信 生産者と消費者モデル スレッド スレッド とはスレッド を使用する理由
スレッドを作成する2つの方法 スレッドオブジェクトのプロパティ スレッド反発ロック 今日の内容 GILグローバルインタプリタロック マルチスレッドの役割 計算密集型 IO密集型 デッドロック 再帰ロック(RLock) 信号量(semaphore) スレッドキュー FIFOキュー(Queue() LIFOキュー(lifoQueue() 優先キュー(PriorityQueue()
同時をシリアルにし、効率を犠牲にして、パケットを稼いでデータの安全を稼ぎました.
メモリにキュースペースを開くことに相当し、データの山を格納し、「先進的な先発」、パイプ(ブロック)+ロックに従うことができます.
プロセス間のデータは共有されず、キューによる通信が可能
生産者:生産データの
消費者:データを使用する
目的:このモデルをキューで実現し、需給のアンバランス問題を解決する
プロセス:実行単位
スレッド:実行単位
注:プロセスを開くとスレッドがあり、プロセスが終了すると破棄されます.
メモリリソースの節約オープンスレッド 新しいメモリ領域を開く には、プライマリスレッド が付属します.
オープンスレッド 1プロセスは、複数のスレッド を開くことができる.オープンスレッドのリソースはプロセス よりはるかに小さい.
Cpythonに基づいてGILを研究する GILは本質的に反発ロック である.は、同じプロセスで複数のスレッドが同時に実行されることを阻止する.すなわち、単一プロセスでは複数のスレッドが並列に実行できず、 しか並列に実行できない. GILの存在はスレッドの安全(ゴミ回収機構) を保証するためである.
注意:複数のスレッドが実行され、IO操作に遭遇するとすぐにGILグローバル解釈器ロックが解放されます.
シングルコアの場合、マルチスレッドが優先されます
マルチコアの場合、マルチプロセスを優先的に使用
まとめ:現在、ほとんどのコンピュータはマルチコアなので、コンピューティングが密集しているマルチプロセスを使用しています.
シングルコアの場合、マルチスレッドが優先されます
マルチコアの場合、マルチスレッドが優先されます
まとめ:IO密集型マルチスレッド使用
効率的に複数のIO密集型のプログラムを実行する:マルチプロセス+マルチスレッドを使用する
デッドロック現象:2つ以上のプロセスまたはスレッドが実行中にリソースを争うことによって互いに待つ現象であり、システムがデッドロック状態にあるか、デッドロックが発生したと呼ばれる.
内部メンテナの1つのLockとcounter変数、counterはacquireの回数を記録して、releaseはcounterの回数を1減らして、counterが0の時だけ使用することができます
デッドロックの問題を解決するために使用されます.チェーンロックに相当します.使わないか、一緒に持って行きます.
信号量:内蔵カウンタ、acquire内蔵カウンタ-1を呼び出すたびにrelease内蔵カウンタ+1を呼び出す.カウンタは0を下回ってはならない.カウンタが0の場合、acquireは他のスレッドがreleaseを呼び出すまでスレッドをブロックする
ロックショップに相当
先入れ先出し
後進後出
まず最初のパラメータからasciiテーブルの数値サイズ を判断する.第2パラメータにおける漢字順 を判断する.再判断第2パラメータ中数字-->文字列数字--->中国語 はこのように を押す.
昨日の内容
プロセス反発ロック
同時をシリアルにし、効率を犠牲にして、パケットを稼いでデータの安全を稼ぎました.
mutex = Lock()
#
mutex.acquire()
#
mutex.release()
キュー
メモリにキュースペースを開くことに相当し、データの山を格納し、「先進的な先発」、パイプ(ブロック)+ロックに従うことができます.
q = Queue()
q.put() # , ,
q.put_nowait() # ,
q.get() # , ,
q.get_nowait() # , ,
q.empty() #
q.full() #
プロセス間通信
プロセス間のデータは共有されず、キューによる通信が可能
生産者と消費者モデル
生産者:生産データの
消費者:データを使用する
目的:このモデルをキューで実現し、需給のアンバランス問題を解決する
スレッド
スレッドとは
プロセス:実行単位
スレッド:実行単位
注:プロセスを開くとスレッドがあり、プロセスが終了すると破棄されます.
スレッドを使用する理由
メモリリソースの節約
スレッドを作成する2つの方法
# 1
from threading import Thread
def task():
pass
t = Thread(target = task)
t.start()
# 2
class MyThread(Thread):
def run():
pass
t= MyThread()
t.start()
スレッドオブジェクトのプロパティ
current_thread().name #
enumerate() #
activeCount() #
is_alive() #
スレッド反発ロック
from threading import Thread
mutex = Lock()
mutex.acquire()
#
mutex.release(
今日の内容
GILグローバルインタプリタロック
Cpythonに基づいてGILを研究する
注意:複数のスレッドが実行され、IO操作に遭遇するとすぐにGILグローバル解釈器ロックが解放されます.
from threading import Thread
import time
number = 100
def task():
global number
number2 = number
time.sleep(1)
nunmer = number2 -1
for i in range(100):
t = Thread(target = task)
t.start()
マルチスレッドの役割
コンピューティング密集型
シングルコアの場合、マルチスレッドが優先されます
マルチコアの場合、マルチプロセスを優先的に使用
まとめ:現在、ほとんどのコンピュータはマルチコアなので、コンピューティングが密集しているマルチプロセスを使用しています.
from multiprocessing import Process
from threading import Thread
import os,time
def work():
res = 0
for i in range(100000000):
res*=i
if __name__ == '__main__':
l = []
print(os.cpu_count())
start = time.time()
for i in range(4):
p = Process(target = work)
# p = Thread(target = work)
l.append(p)
p.start()
for p in l:
p.join()
stop = time.time()
print(f'{stop-start}')
IO密集型
シングルコアの場合、マルチスレッドが優先されます
マルチコアの場合、マルチスレッドが優先されます
まとめ:IO密集型マルチスレッド使用
from multiprocessing import Process
from threading import Thread
import os,time
def work():
time.sleep(2)
print('>>>>>>>>>')
if __name__ == '__main__':
l = []
print(os.cpu_count())
start = time.time()
for i in range(40):
# p = Process(target = work)
p = Thread(target = work)
l.append(p)
p.start()
for p in l:
p.join()
stop = time.time()
print(f'{stop-start}')
効率的に複数のIO密集型のプログラムを実行する:マルチプロセス+マルチスレッドを使用する
デッドロック
デッドロック現象:2つ以上のプロセスまたはスレッドが実行中にリソースを争うことによって互いに待つ現象であり、システムがデッドロック状態にあるか、デッドロックが発生したと呼ばれる.
import time
from threading import Lock,Thread
mutex1 = Lock()
mutex2 = Lock()
def task():
work1()
work2()
def work1():
mutex1.acquire()
print(' 1')
mutex2.acquire()
print(' 2')
mutex2.release()
print(' 1')
mutex1.release()
print(' 2')
def work2():
mutex2.acquire()
time.sleep(1)
mutex1.acquire()
print(' 2')
mutex1.release()
print(' 1')
mutex2.release()
print(' 2')
for i in range(10):
t = Thread(target=task)
t.start()
再帰ロック(RLock)
内部メンテナの1つのLockとcounter変数、counterはacquireの回数を記録して、releaseはcounterの回数を1減らして、counterが0の時だけ使用することができます
デッドロックの問題を解決するために使用されます.チェーンロックに相当します.使わないか、一緒に持って行きます.
import time
from threading import RLock,Thread
mutex1 = mutex2= RLock()
def task():
work1()
work2()
def work1():
mutex1.acquire()
print(' 1')
mutex2.acquire()
print(' 2')
mutex2.release()
print(' 1')
mutex1.release()
print(' 2')
def work2():
mutex2.acquire()
time.sleep(1)
mutex1.acquire()
print(' 2')
mutex1.release()
print(' 1')
mutex2.release()
print(' 2')
for i in range(10):
t = Thread(target=task)
t.start()
しんごうりょう
信号量:内蔵カウンタ、acquire内蔵カウンタ-1を呼び出すたびにrelease内蔵カウンタ+1を呼び出す.カウンタは0を下回ってはならない.カウンタが0の場合、acquireは他のスレッドがreleaseを呼び出すまでスレッドをブロックする
ロックショップに相当
import time
from threading import Lock,Thread,Semaphore
sm = Semaphore(10)
def task():
work1()
work2()
def work1():
sm.acquire()
print(' 1')
sm.acquire()
print(' 2')
sm.release()
print(' 1')
sm.release()
print(' 2')
def work2():
sm.acquire()
time.sleep(1)
sm.acquire()
print(' 2')
sm.release()
print(' 1')
sm.release()
print(' 2')
for i in range(10):
t = Thread(target=task)
t.start()
スレッドキュー
FIFOキュー(Queue()
先入れ先出し
import queue
q=queue.Queue()
q.put('first')
q.put('second')
q.put('third')
print(q.get())
print(q.get())
print(q.get())
'''
( ):
first
second
third
'''
LIFOキュー(lifoQueue()
後進後出
import queue
q=queue.LifoQueue()
q.put('first')
q.put('second')
q.put('third')
print(q.get())
print(q.get())
print(q.get())
'''
( ):
third
second
first
'''
優先順位キュー(PriorityQueue()
import queue
q=queue.PriorityQueue()
#put , ( , ),
q.put((20,'a'))
q.put((10,'b'))
q.put((30,'c'))
print(q.get())
print(q.get())
print(q.get())
'''
( , ):
(10, 'b')
(20, 'a')
(30, 'c')
'''