GILの章XV、Pythonのセマフォとマルチスレッド

GILの章XV、Pythonのセマフォとマルチスレッド

1.セマフォ(セマフォ)

()の呼び出しが-1、呼解放(時間)+1を取得するたびに、セマフォは、同時スレッドの数、内蔵カウンタのセマフォ管理を制御するために使用されます。別のスレッドがリリースを起動するまで、カウンタ)(カウンタが0である場合、0未満で取得することができない)(ロック同期するスレッドをブロックします。実際には、リソースの操作を共有できるスレッドの最大数を制御します。

import threading
import time

semaphore = threading.Semaphore(5)

def func():
    if semaphore.acquire():
        print (threading.currentThread().getName() + '获取共享资源')
        time.sleep(2)
        semaphore.release()

for i in range(10)
  t1 = threading.Thread(target=func)
  t1.start()
--------------------------------------------------
Thread-1获取共享资源
Thread-2获取共享资源
Thread-3获取共享资源
Thread-4获取共享资源
Thread-5获取共享资源

Thread-6获取共享资源
Thread-8获取共享资源
Thread-7获取共享资源
Thread-9获取共享资源
Thread-10获取共享资源

上記の簡単な例は、10個のスレッドを作成することですので、ちょうどすべての5つのスレッドが関数funcを実行してみましょう。

結果:バッチ印刷、中絞り-2Sにバッチを実行する5つのスレッド

2. GIL

意味:グローバルインタプリタロックを。

役割:関係なく、あなたが開始どのように多くのスレッド、あなたはCPUの数を持っていない、Pythonは(スレッド間の競争)の実装で唯一つのスレッドを許可すると同時に、GILはCPU上で実行すると、スレッドの出会いを取得しますIO待ち時間またはポーリングの到着時、CPUは他のスレッドを与えるために、スイッチ、CPU時間スライスを行います、CPUのスイッチは、時間とリソースを消費するので、(例えば、加算、減算、乗算、除算など)の機能を集中-計算マルチは適していませんスレッド、マルチスレッドのためにあまりにも多くのCPUスレッドスイッチ、IO集約型より適切なため。

タスク:

  • IOは(待つことがある場合、各スレッドは、スレッドの切り替えがより適切である、ウェイトの様々な構造を有するであろう)集中、また、コルーチンができるマルチプロセスで使用することができます+

  • 計算集約的(計算には待機中のスレッドは、切り替えるには、この時間は、スイッチは無用である)、Pythonはそのような機能の開発に適しておりません

    私たちは、IOが発生すると同等、実際には、睡眠の動作をシミュレートし、以前の例を上げ、複数のスレッドを使用してこのシナリオでは、パフォーマンスを向上させることができますが、我々は、データの計算を計算するために複数のスレッドを使用している場合、パフォーマンスが低下します。

それを証明します:

from threading import Thread
from multiprocessing import Process
import time

#计算密集型
def work1():
    res=0
    for i in range(100000000): #1+8个0
        res*=i

if __name__ == '__main__':
    t_list = []
    start = time.time()
    for i in range(4):
        # t = Thread(target=work1)
        t = Process(target=work1)
        t_list.append(t)
        t.start()
    for t in t_list:
        t.join()
    end = time.time()
    # print('多线程',end-start) # 多线程 15.413789510726929
    print('多进程',end-start) # 多进程 4.711405515670776
from threading import Thread
from multiprocessing import Process
import time
# io密集型
def work1():
    x = 1+1
    time.sleep(5)


if __name__ == '__main__':
    t_list = []
    start = time.time()
    for i in range(4):
        t = Thread(target=work1)
        # t = Process(target=work1)
        t_list.append(t)
        t.start()
    for t in t_list:
        t.join()
    end = time.time()
    print('多线程',end-start) #  多线程 5.002625942230225
    # print('多进程',end-start) # 多进程 5.660863399505615

説明:

在Cpython解释器中有一把GIL锁(全局解释器锁),GIl锁本质是一把互斥锁。
导致了同一个进程下,同一时间只能运行一个线程,无法利用多核优势.
同一个进程下多个线程只能实现并发不能实现并行.
为什么要有GIL?
因为cpython自带的垃圾回收机制不是线程安全的,所以要有GIL锁.
导致了同一个进程下,同一时间只能运行一个线程,无法利用多核优势.
分析:我们有四个任务需要处理,处理方式肯定是要玩出并发的效果,解决方案可以是:
方案一:开启四个进程
方案二:一个进程下,开启四个线程
计算密集型 推荐使用多进程
 每个都要计算10s
 多线程
 在同一时刻只有一个线程会被执行,也就意味着每个10s都不能省,分开每个都要计算10s,共40.ns
 多进程
 可以并行的执行多个线程,10s+开启进程的时间

おすすめ

転載: www.cnblogs.com/demiao/p/11545466.html