恐怕我還是有點困惑(儘管檢查其它線程)是否:這是多線程功能異步
- 所有異步代碼是多線程
- 所有的多線程功能是異步
我最初的猜測是沒有這兩個和適當的異步代碼應該能夠在一個線程中運行 - 但它可以通過增加線程例如,像這樣進行改進:
所以我寫這個玩具的例子:
from threading import *
from queue import Queue
import time
def do_something_with_io_lag(in_work):
out = in_work
# Imagine we do some work that involves sending
# something over the internet and processing the output
# once it arrives
time.sleep(0.5) # simulate IO lag
print("Hello, bee number: ",
str(current_thread().name).replace("Thread-",""))
class WorkerBee(Thread):
def __init__(self, q):
Thread.__init__(self)
self.q = q
def run(self):
while True:
# Get some work from the queue
work_todo = self.q.get()
# This function will simiulate I/O lag
do_something_with_io_lag(work_todo)
# Remove task from the queue
self.q.task_done()
if __name__ == '__main__':
def time_me(nmbr):
number_of_worker_bees = nmbr
worktodo = ['some input for work'] * 50
# Create a queue
q = Queue()
# Fill with work
[q.put(onework) for onework in worktodo]
# Launch processes
for _ in range(number_of_worker_bees):
t = WorkerBee(q)
t.start()
# Block until queue is empty
q.join()
# Run this code in serial mode (just one worker)
%time time_me(nmbr=1)
# Wall time: 25 s
# Basically 50 requests * 0.5 seconds IO lag
# For me everything gets processed by bee number: 59
# Run this code using multi-tasking (launch 50 workers)
%time time_me(nmbr=50)
# Wall time: 507 ms
# Basically the 0.5 second IO lag + 0.07 seconds it took to launch them
# Now everything gets processed by different bees
它是異步的?
對我來說這段代碼似乎並不是異步的,因爲它是我的示例圖中的圖3。 I/O調用阻塞了線程(儘管我們並不覺得它是因爲它們被並行阻塞)。
但是,如果這是我很困惑,爲什麼要求期貨被認爲是異步的,因爲它是周圍的ThreadPoolExecutor的包裝情況:
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
future_to_url = {executor.submit(load_url, url, 10): url for url in get_urls()}
for future in concurrent.futures.as_completed(future_to_url):
url = future_to_url[future]
try:
data = future.result()
可以在只有一個線程這個功能呢?
尤其是相對於asyncio時,這意味着它可以運行單線程
只有兩種方式可以讓一個程序在單一處理器上做 「不止一兩件事的時間。」多線程編程是最簡單也是最流行的方式,但還有另外一種非常不同的技術,它可以讓你擁有幾乎所有的多線程優點,而不需要實際使用多線程。這真的是 只有在你的程序很大程度上受I/O限制的情況下才有用。如果你的程序 是處理器綁定的,那麼搶先調度的線程可能是你真正需要的 。網絡服務器幾乎不受處理器限制,但是。
代碼不是異步的,代碼執行是。函數不是多線程的,函數調用是。有鑑於此,你的問題是錯誤/不清楚的。 –