スレッドキューイベントイベントコルーチン

キュー

import queue
q = queue.Queue(3)
q.put(1)
q.put(2)
q.put(3)
print(q.get())
print(q.get())
print(q.get())
"""
1
2
3
"""

スタック

t = queue.LifoQueue(4)
t.put(1)
t.put(2)
t.put(3)
t.put(4)
print(t.get())
print(t.get())
print(t.get())
print(t.get())
"""
4
3
2
1
"""

プライオリティキュー

p = queue.PriorityQueue(4)
p.put((5,"oifjanior"))
p.put((-2,"hshts"))
p.put((0,"shtr"))
p.put((3,"hstrhs"))
print(p.get())
print(p.get())
print(p.get())
print(p.get())
"""
(-2,"hshts")
(0,"shtr")
(3,"hstrhs")
(5,"oifjanior")
"""

イベントイベント

プログラムを必要としている他のスレッドは、スレッドの状態を判断して、その次の行動を決定する場合

バージョン

from threading import current_thread, Thread
import time

flag = False
def check():
    print(f"{current_thread().name}监测服务器是否开启")
    time.sleep(3)
    global flag
    flag = True
    print("服务器已经开启")

def connect():
    while 1:
        print(f"{current_thread().name}等待连接...")
        time.sleep(0.5)
        if flag:
            print(f"{current_thread().name}连接成功...")
            break
t1 = Thread(target=check)
t2 = Thread(target=connect)
t1.start()
t2.start()
"""
Thread-1监测服务器是否开启
Thread-2等待连接...
Thread-2等待连接...
Thread-2等待连接...
Thread-2等待连接...
Thread-2等待连接...
Thread-2等待连接...
服务器已经开启
Thread-2连接成功...
"""

バージョン2

from threading import Thread, current_thread, Event
import time

event = Event()
def check():
    print(f"{current_thread().name} 监测服务器是否开启...")
    time.sleep(3)
    print(event.is_set()) 
    # 判断事件是否开启
    event.set()
    print(event.is_set())
    print("服务器已经开启...")

def connect():
    print(f"{current_thread().name} 等待连接...")
    event.wait() 
    # 阻塞, 直到 event.set() 方法之后
    # event.wait(1) 只阻塞1秒, 1秒之后如果还没有进行set 直接进行下一步操作
    print(f"{current_thread().name}连接成功...")

t1 = Thread(target=check)
t2 = Thread(target=connect)
t1.start()
t2.start()

開いた二つのスレッド、ステージの中央にあるスレッドの実行、別のスレッドをトリガする二つのスレッドを実行し、結合を増加させます

練習

かどうかは、それは接続が成功であることを示し、3回だけ、1秒以上3倍であれば、いったんこのスレッドを接続しようと、別のスレッドが開始するかどうかを決定するために、スレッド・サーバの監視を開始するには、まだ接続が成功し、それは接続に失敗した示しています。

from threading import current_thread,Thread,Event
import time

event = Event()
def check():
    print(f"{current_thread().name}监测服务器是否开启...")
    time.sleep(4)
    event.set()
    print("服务器已开启")

def connect():
    count = 1
    while not event.is_set():
        if count == 4:
            print("连接次数过多, 已断开")
            break
        event.wait(1)
        print(f"{current_thread().name}尝试连接{count}次")
        count += 1
    else:
        print(f"{current_thread().name}连接成功..")

t1 = Thread(target=check)
t2 = Thread(target=connect)
t1.start()
t2.start()

コルーチン

スレッド同時処理タスク

シリアル:

実行が完了した後、タスクを実行中のスレッド、次のタスク。

パラレル:

複数のCPUが複数のタスクを実行するために、4つのCPUは、4つのタスクを実行します

同時実行:

実行のような同じ時間ルックスで複数のタスクを実行するためのCPU

同時自然:

保持状態の切り替え+

マルチスレッド・マップ

3スレッド10は、スレッド1の処理の経験が他のスレッドに切り替えるには、オペレーティングシステムによって、CPUをブロックする場合は、このクエスト

シングルスレッドの同時実行マップ

3つのタスクを処理する1つのスレッド

同時方法:

シングルCPU、タスク10の同時実行

複数のプロセスの同時実行の電源を入れ、オペレーティングシステムをホールド+に切り替えられました

複数のスレッドの同時実行2.電源を入れ、オペレーティングシステムをホールド+に切り替えられました

CPU、スイッチングバックと3つのタスクが保持等の間を制御する独自の手順3. [コルーチン実行同時+

詳細第三の道

コルーチンスイッチング速度が非常に高速で、目のオペレーティングシステムに目がくらんで、オペレーティング・システムは、このCPUは、スレッド(コルーチン)を実行されたことを信じてみましょう

最良の方法

オーバーヘッドが小さいのでコルーチン、高速で、CPUのコルーチンの長期占領は、私はちょうどプログラム内のすべてのタスクを実行します。

コルーチンプロセスを使用した高効率IO集約、計算集約、シリアルの使用または

コルーチン

シングルスレッド同時処理タスクの複数+プログラム制御保留状態コルーチンを切り替えます

スイッチ

def func1():
    print("in func1")

def func2():
    print("in func2")
    func1()
    print("end")
func2()

ホールドスイッチ+

def gen():
    while 1:
        yield 1

def func():
    obj = gen()
    for i in range(10):
        next(obj)
func()

コルーチン

import gevent
from gevent import monkey

monkey.patch_all()
def eat(name):
    print(f"{name} eat 1")
    gevent.sleep(2)
    print(f"{name} eat 2")

def play(name):
    print(f"{name} play 1")
    gevent.sleep(1)
    print(f"{name} play 2")

g1 = gevent.spawn(eat, "egon")
g2 = gevent.spawn(play, "egon")

gevent.joinall([g1,g2])

コルーチン機能

1.における単一のスレッドで同時に実施されなければなりません

ロックせず2.変更共有データ

フロー制御のそれらのスタック複数の保存3.ユーザプログラムのコンテキスト(ホールド)

4.その他:コルーチン遭遇IO操作が自動的に別のコルーチンに切り替えられ

仕事

​ 一般在工作中我们都是进程+线程+协程的方式来实现并发,以达到最好的并发效果,如果是4核的cpu,一般起5个进程,每个进程中20个线程(5倍cpu数量),每个线程可以起500个协程,大规模爬取页面的时候,等待网络延迟的时间的时候,我们就可以用协程去实现并发。 并发数量 = 5 * 20 * 500 = 50000个并发,这是一般一个4cpu的机器最大的并发数。nginx在负载均衡的时候最大承载量就是5w个单线程里的这20个任务的代码通常会既有计算操作又有阻塞操作,我们完全可以在执行任务1时遇到阻塞,就利用阻塞的时间去执行任务2。。。。如此,才能提高效率,这就用到了Gevent模块

おすすめ

転載: www.cnblogs.com/beichen123/p/11936717.html