ホームページ  >  記事  >  バックエンド開発  >  Python のスレッド同期プリミティブのコード例

Python のスレッド同期プリミティブのコード例

不言
不言転載
2018-11-20 16:06:093054ブラウズ

この記事では、Python のスレッド同期プリミティブに関するコード例を紹介します。一定の参考値があります。必要な友人は参照できます。お役に立てれば幸いです。

Threading モジュールは、Python3 のマルチスレッド モジュールです。このモジュールには、Thread、Condition、Event、Lock、Rlock、Semaphore、Timer などの多くのクラスが統合されています。次の記事では、主にケースを使用してイベントとセグマフォ (境界セグマフォ) の使用法を説明します。

#Event

#Event クラスは、イベントが待機中かどうかをマークするための flags パラメータを内部的に格納します。

イベント クラス インスタンス関数

1.set() フラグを True に設定すると、イベントのブロックが停止します

2.clear() フラグを False にリセットし、フラグを削除します。イベントは再ブロックされます

3. wait() はイベントを待機状態に設定します

4.

is_set() はフラグが設定されているかどうかを判断し、設定されている場合は True を返します。それ以外の場合は False を返します

(1) 単一のイベントは他のイベントの発生を待機します

特定のコード:

from time import ctime,sleep
event = Event()

def event_wait():
    print(ctime())
    event.wait()
    print('这是event_wait方法中的时间',ctime())

def event_set(n):
    sleep(n)
    event.set()
    print('这是event_set方法中的时间', ctime())

thread1 = Thread(target=event_wait)
thread2 = Thread(target=event_set,args=(3,))

thread1.start()
thread2.start()

結果:

Sat Nov 17 10:01:05 2018
这是event_wait方法中的时间 Sat Nov 17 10:01:08 2018
这是event_set方法中的时间  Sat Nov 17 10:01:08 2018

(2) 複数のイベントが次々と発生しました

レースを例。 5 本の滑走路があり、それぞれに 1 人のアスリート ABCDE がいると仮定します。

特定のコード:

from threading import Event
from  threading import Thread
import threading

event = Event()

def do_wait(athlete):
    racetrack = threading.current_thread().getName()
    print('%s准备就绪' % racetrack)
    event.wait()
    print('%s听到枪声,起跑!'%athlete)

thread1 = Thread(target=do_wait,args=("A",))
thread2 = Thread(target=do_wait,args=("B",))
thread3 = Thread(target=do_wait,args=("C",))
thread4 = Thread(target=do_wait,args=("D",))
thread5 = Thread(target=do_wait,args=("E",))

threads = []
threads.append(thread1)
threads.append(thread2)
threads.append(thread3)
threads.append(thread4)
threads.append(thread5)

for th in threads:
    th.start()

event.set()  #这个set()方法很关键,同时对5个线程中的event进行set操作

結果:

Thread-1准备就绪
Thread-2准备就绪
Thread-3准备就绪
Thread-4准备就绪
Thread-5准备就绪
E听到枪声,起跑!
A听到枪声,起跑!
B听到枪声,起跑!
D听到枪声,起跑!
C听到枪声,起跑!

Yes複数のスレッドでのイベントの set() はランダムであり、その内部実装は notify_all() メソッドによるものであることがわかります。このメソッドは、ロックされているすべてのイベントを一度に解放します。最初に実行されているスレッドのタイム スライスを取得したスレッドが最初にロックを解放します。

1 つの set() 関数を呼び出すだけですべてのイベントの終了をブロックできる理由は、event.wait() がスレッド内に実装され、set() 関数がプロセス内で呼び出されるためです。 -スレッドはプロセス メモリ空間を共有します。これら 2 つの関数が異なるプロセスで呼び出された場合、これは実現できません。

BoundedSegmaphore

ホストが IO 集中型のタスクを実行し、その後、短時間で多数のタスク (マルチスレッド) を完了するプログラムを実行すると、コンピュータはダウンしている可能性が高くなります。

現時点では、このプログラムにカウンター関数を追加して、ある時点のスレッド数を制限できます。 IO操作を行うたびにセグマフォにリソース(ロック)を要求する必要があり、要求されていない場合はブロックして待機し、要求が成功した場合のみタスクを実行するような感じになります。

BoundedSegmaphore と Segmaphore の違い

BoundedSegmaphore によって要求されたロックの数は渡されたパラメーターに固定されますが、Segmaphore によって要求されたロックの数は渡されたパラメーターを超えることができます。

主な機能:

1.acquire() ロックの要求

2. release() ロックの解除

以下は家を借りる例です。これを説明するために、ロックの数を固定するメカニズムを示します。小さなアパートに 6 部屋あり、当初は 2 人の住人が住んでいたとします。

具体的なコード実装:

from threading import BoundedSemaphore,Lock,Thread
from time import sleep
from random import randrange

lock = Lock()
num = 6
hotel = BoundedSemaphore(num)

def logout():
    lock.acquire()
    print('I want to logout')
    print('A customer logout...')
    try:
        hotel.release()
        print('Welcome again')
    except ValueError:
        print('Sorry,wait a moment.')
    lock.release()

def login():
    lock.acquire()
    print('I want to login')
    print('A customer login...')
    if hotel.acquire(False):
        print('Ok,your room number is...')
    else:
        print('Sorry,our hotel is full')
    lock.release()

#房东
def producer(loops):
    for i in range(loops):
        logout()
        print('还剩%s' % hotel._value, '房间')
        sleep(randrange(2))
#租客
def consumer(loops):
    for i in range(loops):
        login()
        print('还剩%s' % hotel._value, '房间')
        sleep(randrange(2))
def main():
    print('Start')
    room_num = hotel._value
    print('The hotel is full with %s room'%room_num)
    #原本有2个住户
    hotel.acquire()
    hotel.acquire()
    thread1 = Thread(target=producer,args=(randrange(2,8),))
    thread2 = Thread(target=consumer,args=(randrange(2,8),))
    thread1.start()
    thread2.start()

if __name__ == '__main__':
    main()

結果:

The hotel is full with 6 room
I want to logout
A customer logout...
Welcome again
还剩5 房间
I want to logout
A customer logout...
Welcome again
还剩6 房间
I want to login
A customer login...
Ok,your room number is...
还剩5 房间
I want to login
A customer login...
Ok,your room number is...
还剩4 房间

部屋の数 _value 値 (BoundedSegmaphore 内のカウンター) は受信パラメーター 6 でなければならないため、6 を超えることはありません。

以上がPython のスレッド同期プリミティブのコード例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。