執行緒的queue,類似於程序
作用也是類似,queue(n)規範放入值的數量
這個和之前一樣是為了實現先進先出
import queue
q = queue.queue(2) # 括號內可加入數字規範放入值的數量,不加則不會規範
q.put('123')
q.put('qweqwe')
# q.put('111')
print(q.get())
print(q.get())
# print(q.get())
q.task_done()
q.join()
獲得的結果是先get到『123』
在這裡如果加入多的q.put程式會阻塞,queue.queue()則不會
這則可以實現先進後出的效果
import queue
q = queue.lifoqueue() #堆疊 先進後出
q.put('蕾姆')
q.put('炭治郎')
q.put('綾乃')
print(q.get())
print(q.get())
print(q.get())
結果為:
綾乃炭治郎
蕾姆執行緒定時器可以設定預設幾秒後開啟乙個執行緒,用t = timer(n,執行緒名)來表示
from threading import thread,timer
import time
def task():
print('執行緒執行了')
time.sleep(2)
print('執行緒結束了')
t = timer(4,task) # 過了4s後開啟了乙個執行緒
t.start()
# print('hyc')
程序池執行緒池:
池的功能限制程序數或執行緒數.
什麼時候限制?
當併發的任務數量遠遠大於計算機所能承受的範圍,即無法一次性開啟過多的任務數量
就應該考慮去限制程序數或執行緒數,從保證伺服器不崩.
from concurrent.futures import processpoolexecutor,threadpoolexecutor
from threading import currentthread
from multiprocessing import current_process
import time
def task(i):
print(f' 在執行任務 ')
# print(f'程序 在執行任務 ')
time.sleep(1)
return i**2
if __name__ == '__main__':
pool = threadpoolexecutor(4) # 池子裡只有4個執行緒
# pool = processpoolexecutor(4) # 池子裡只有4個執行緒
fu_list =
for i in range(20):
# pool.submit(task,i) # task任務要做20次,4個執行緒負責做這個事
future = pool.submit(task,i) # task任務要做20次,4個程序負責做這個事
# print(future.result()) # 如果沒有結果一直等待拿到結果,導致了所有的任務都在序列
pool.shutdown() # 關閉了池的入口,會等待所有的任務執行完,結束阻塞.
for fu in fu_list:
print(fu.result())
理解為提交任務的兩種方式
同步: 提交了乙個任務,必須等任務執行完了(拿到返回值),才能執行下一行**,
非同步: 提交了乙個任務,不要等執行完了,可以直接執行下一行**.
from concurrent.futures import processpoolexecutor,threadpoolexecutor
from threading import currentthread
from multiprocessing import current_process
import time
def task(i):
print(f' 在執行任務 ')
# print(f'程序 在執行任務 ')
time.sleep(1)
return i**2
def parse(future):
# 處理拿到的結果
print(future.result())
if __name__ == '__main__':
pool = threadpoolexecutor(4) # 池子裡只有4個執行緒
# pool = processpoolexecutor(4) # 池子裡只有4個執行緒
fu_list =
for i in range(20):
# pool.submit(task,i) # task任務要做20次,4個執行緒負責做這個事
future = pool.submit(task,i) # task任務要做20次,4個程序負責做這個事
future.add_done_callback(parse)
# 為當前任務繫結了乙個函式,在當前任務執行結束的時候會觸發這個函式,
# 會把future物件作為引數傳給函式
# 這個稱之為**函式,處理完了回來就呼叫這個函式.
# print(future.result()) # 如果沒有結果一直等待拿到結果,導致了所有的任務都在序列
# pool.shutdown() # 關閉了池的入口,會等待所有的任務執行完,結束阻塞.
# for fu in fu_list:
# print(fu.result())
python的執行緒用的是作業系統原生的執行緒
協程:單執行緒下實現併發
併發:切換+儲存狀態
多執行緒:作業系統幫你實現的,如果遇到io切換,執行時間過長也會切換,實現乙個雨露均沾的效果.
什麼樣的協程是有意義的?
遇到io切換的時候才有意義
具體:協程概念本質是程式設計師抽象出來的,作業系統根本不知道協程存在,也就說來了乙個執行緒我自己遇到io 我自己執行緒內部直接切到自己的別的任務上了,作業系統跟本發現不了,
也就是實現了單執行緒下效率最高.
優點:自己控制切換要比作業系統切換快的多
缺點:對比多執行緒
自己要檢測所有的io,但凡有乙個阻塞整體都跟著阻塞.
對比多程序
無法利用多核優勢.
為什麼要有協程(遇到io切換)?
自己控制切換要比作業系統切換快的多.降低了單個執行緒的io時間,
我們可以用協程來寫乙個沒有io的**
import time
def eat():
print('eat 1')
# 瘋狂的計算呢沒有io
time.sleep(2)
# for i in range(100000000):
# i+1
def play():
print('play 1')
# 瘋狂的計算呢沒有io
time.sleep(3)
# for i in range(100000000):
# i+1
play()
eat() # 5s
import time
def func1():
while true:
1000000+1
yield
def func2():
g = func1()
for i in range(100000000):
i+1next(g)
start = time.time()
func2()
stop = time.time()
print(stop - start)
它執行用了22秒的時間
如果我們不用協程去完成它會怎麼樣呢
import time
def func1():
for i in range(100000000):
i+1def func2():
for i in range(100000000):
i+1start = time.time()
func1()
func2()
stop = time.time()
print(stop - start) # 8.630893230438232
只用了8秒
可見,在沒有io的情況下,不建議用協程。相反,有大量io的時候,協程就比較佔優勢了。而我們平時敲得**都含有大量的io
from gevent import monkey;monkey.patch_all() #打了乙個補丁,可以實現捕獲非gevent的io.
import gevent
import time
def eat():
print('eat 1')
time.sleep(2)
print('eat 2')
def play():
print('play 1')
# 瘋狂的計算呢沒有io
time.sleep(3)
print('play 2')
start = time.time()
g1 = gevent.spawn(eat)
g2 = gevent.spawn(play)
g1.join()
g2.join()
end = time.time()
print(end-start) # 3.0040290355682373
執行緒佇列 執行緒池 協程
1 執行緒佇列 from multiprocessing queue joinablequeue 程序ipc佇列 from queue import queue 執行緒佇列 先進先出 from queue import lifoqueue 後進先出的 方法都是一樣的 put get put nowa...
python執行緒池 協程
python的執行緒雖然是真正的執行緒,但直譯器執行 時,有乙個gil鎖 global interpreter lock,任何python執行緒執行前,必須先獲得gil鎖,然後,每執行100條位元組碼,直譯器就自動釋放gil鎖,讓別的執行緒有機會執行。這個gil全域性鎖實際上把所有執行緒的執行 都給...
併發程式設計 執行緒池程序池協程
1.socket服務端實現併發 現在回來想網路程式設計服務端需要滿足哪幾點需求 2.程序池執行緒池介紹 執行緒不可能無限制的開下去,總要消耗和占用資源 程序池執行緒池概念 硬體有極限,為了減輕硬體壓力,所以有了池的概念 注意協程這個概念完全是程式設計師自己想出來的東西,它對於作業系統來說根本不存在。...