python3並行プログラミング4

イベントイベント

  • スレッドの実行を制御するために使用します
  • e.isSet()現在の信号状態オブジェクトを参照してください電子、デフォルトはFalseです
  • e.wait() 信号の状態は、その後、現在のスレッドがブロックされているFalseです
  • e.set() 信号状態eがTrueに設定され、ブロックされたスレッドがブロックされていないとなり
from threading import Thread
from threading import Event
import time

e = Event()


def light():
    print('*********红灯!**********')
    print(f'对象当前的信号状态为{e.isSet()}')
    time.sleep(5)
    print('*********绿灯!**********')
    e.set()  # 将e的信号标准设为True
    print(f'对象当前的信号状态为{e.isSet()}')


def driver(name):
    print(f'{name}正在等红灯!')
    e.wait()  # 如果e信号标志为False, 则当前线程阻塞
    print(f'{name}弹射起步!')


if __name__ == '__main__':

    t1 = Thread(target=light)
    t1.start()

    for i in range(10):
        t2 = Thread(target=driver, args=(f'老司机{i+1}号',))
        t2.start()

        
'''
**********红灯!**********
对象当前的信号状态为False
老司机1号正在等红灯!
老司机2号正在等红灯!
老司机3号正在等红灯!
老司机4号正在等红灯!
老司机5号正在等红灯!
老司机6号正在等红灯!
老司机7号正在等红灯!
老司机8号正在等红灯!
老司机9号正在等红灯!
老司机10号正在等红灯!
**********绿灯!**********
对象当前的信号状态为True
老司机1号弹射起步!
老司机5号弹射起步!
老司机7号弹射起步!
老司机8号弹射起步!
老司机9号弹射起步!
老司机6号弹射起步!
老司机4号弹射起步!
老司机2号弹射起步!
老司机10号弹射起步!
老司机3号弹射起步!
'''

スレッドプールとプロセスプール

基本コンセプト

  • 現在のプログラムの数を制御するために使用しますが、プロセス/スレッドを作成することができます
  • プログラムを防止するためのプロセスは、ハードウェアの手頃な価格の範囲を超えるすぎ/スレッドを作成します

使用

  • pool = ProcessPoolExecutor(5) 5つのタスクを同時に開いているプロセスの現在の最大値は、デフォルトのスレッド数はCPUの数です
  • pool = ThreadPoolExecutor(5) 5つのタスクを同時に開いているスレッドの現在の最大値は、デフォルトのスレッド数は、* 5 CPUの数です
  • pool.submit(函数地址, 参数) ジョブをサブミット
  • pool.submit(函数地址, 参数).add_done_callback(回调函数地址) タスク、およびコールバック関数に渡された戻り値のタスクを送信
  • pool.shutdown() スレッドプールのタスクがダウンコードのそれらの実行後に実行されてみましょう
from concurrent.futures import ThreadPoolExecutor
import time

pool = ThreadPoolExecutor(5)


# 送快递
def deliver(goods):
    print(f'{goods}开始发货!')
    time.sleep(1)
    print(f'{goods}已经签收!')
    return True


# 拿快递(回调函数)
def get_goods(res):
    get = res.result()
    if get:
        print('开始拆快递!')
    else:
        print('投诉!')


for i in range(5):
    pool.submit(deliver, f'格子衬衫牛仔裤{i+1}').add_done_callback(get_goods)

# 让线程池中的线程运行完毕再执行下面的代码
pool.shutdown()
print('钱包空空!')


'''
格子衬衫牛仔裤1开始发货!
格子衬衫牛仔裤2开始发货!
格子衬衫牛仔裤3开始发货!
格子衬衫牛仔裤4开始发货!
格子衬衫牛仔裤5开始发货!
格子衬衫牛仔裤1已经签收!
开始拆快递!
格子衬衫牛仔裤2已经签收!
开始拆快递!
格子衬衫牛仔裤5已经签收!
开始拆快递!
格子衬衫牛仔裤4已经签收!
开始拆快递!
格子衬衫牛仔裤3已经签收!
开始拆快递!
钱包空空!
'''

私たちは10個のスレッドを開きたい場合は、両方のfor i in range(10):結果は次の通りであります

'''
格子衬衫牛仔裤1开始发货!
格子衬衫牛仔裤2开始发货!
格子衬衫牛仔裤3开始发货!
格子衬衫牛仔裤4开始发货!
格子衬衫牛仔裤5开始发货!
格子衬衫牛仔裤2已经签收!
开始拆快递!
格子衬衫牛仔裤6开始发货!
格子衬衫牛仔裤1已经签收!
开始拆快递!
格子衬衫牛仔裤7开始发货!
格子衬衫牛仔裤4已经签收!
格子衬衫牛仔裤3已经签收!
开始拆快递!
格子衬衫牛仔裤8开始发货!
格子衬衫牛仔裤5已经签收!
开始拆快递!
格子衬衫牛仔裤9开始发货!
开始拆快递!
格子衬衫牛仔裤10开始发货!
格子衬衫牛仔裤6已经签收!
开始拆快递!
格子衬衫牛仔裤10已经签收!
开始拆快递!
格子衬衫牛仔裤7已经签收!
开始拆快递!
格子衬衫牛仔裤8已经签收!
开始拆快递!
格子衬衫牛仔裤9已经签收!
开始拆快递!
钱包空空!
'''

そして、差分信号の量

  • セマフォ:当社独自のワーカースレッドが作成され、我々は、手動で制限する必要があります
  • スレッドプール:スレッドプールのワーカースレッドが作成され、スレッドプールを自動的に制限します

コルーチン(コルーチン)

基本コンセプト

  • 同時実行のシングルスレッドの実装では(+スイッチング保存)
  • スレッドは、オペレーティングシステムのスケジューラによって、システムレベルである。コルーチンは、プログラムレベルで、プログラマが自分のスケジュールを必要とします
  • 長所:なしコンテキストは、時間とスペースを節約し、オーバーヘッド切り替えません
  • 欠点は:マルチコアの利点を使用することができない、ブロッキング動作は、プログラム全体をブロックします

実装

  • 収率が達成します
import time


# 生成器
def consumer():
    r = ''
    while True:
        n = yield r
        if not n:
            return
        print(f'[CONSUMER] consuming {n}...')
        time.sleep(1)
        r = '200 OK'


def producer(c):
    c.__next__()  # 初始化生成器
    n = 0
    while n < 5:
        n = n + 1
        print(f'[PRODUCER] producing {n}...')
        r = c.send(n) # 切换到consumer执行
        print(f'[PRODUCER] consumer return: {r}')
    c.close()


if __name__ == '__main__':
    # c是生成器对象
    c = consumer()
    producer(c)
    
'''
[PRODUCER] producing 1...
[CONSUMER] consuming 1...
[PRODUCER] consumer return: 200 OK
[PRODUCER] producing 2...
[CONSUMER] consuming 2...
[PRODUCER] consumer return: 200 OK
[PRODUCER] producing 3...
[CONSUMER] consuming 3...
[PRODUCER] consumer return: 200 OK
[PRODUCER] producing 4...
[CONSUMER] consuming 4...
[PRODUCER] consumer return: 200 OK
[PRODUCER] producing 5...
[CONSUMER] consuming 5...
[PRODUCER] consumer return: 200 OK
'''
  • geventモジュールを実装
from gevent import monkey;
monkey.patch_all()  # 猴子补丁, 修改Python一些标准库
from gevent import spawn, joinall
import time


def func1():
    print('1')
    time.sleep(1)


def func2():
    print('2')
    time.sleep(2)


def func3():
    print('3')
    time.sleep(3)


start_time = time.time()

s1 = spawn(func1)
s2 = spawn(func2)
s3 = spawn(func3)

joinall([s1, s2, s3])

end_time = time.time()

print(end_time - start_time)


'''
1
2
3
3.007172107696533
'''

高性能ビデオクロール梨

おすすめ

転載: www.cnblogs.com/bigb/p/11735534.html