キュー
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模块