Một vài ngày trước, tôi đã hỏi một câu hỏi về việc giúp tôi thiết kế một mô hình để cấu trúc nhiều yêu cầu HTTPSự khác biệt về thông lượng khi sử dụng coroutines vs luồng
Đây là kịch bản. Tôi muốn có một hệ thống đa người sản xuất, đa người tiêu dùng. Các nhà sản xuất của tôi thu thập dữ liệu và loại bỏ một vài trang web và thêm các liên kết mà nó tìm thấy vào hàng đợi. Vì tôi sẽ thu thập dữ liệu nhiều trang web, tôi muốn có nhiều nhà sản xuất/trình thu thập thông tin.
Người tiêu dùng/công nhân cung cấp hàng đợi này, đặt yêu cầu TCP/UDP cho các liên kết này và lưu kết quả vào DB Django của tôi. Tôi cũng muốn có nhiều công nhân vì mỗi mục xếp hàng hoàn toàn độc lập với nhau.
Mọi người đề xuất sử dụng thư viện coroutine cho Gevent hoặc Eventlet này. Chưa bao giờ làm việc với coroutines, tôi đọc rằng mặc dù mô hình lập trình tương tự như mô hình luồng, chỉ có một luồng đang hoạt động tích cực nhưng khi chặn cuộc gọi xảy ra - chẳng hạn như cuộc gọi I/O - ngăn xếp được chuyển vào bộ nhớ và màu xanh lá cây khác chuỗi tiếp quản cho đến khi nó gặp phải một số loại cuộc gọi I/O chặn. Hy vọng rằng tôi có quyền này? Dưới đây là các mã từ một trong những bài viết SO tôi:
import gevent
from gevent.queue import *
import time
import random
q = JoinableQueue()
workers = []
producers = []
def do_work(wid, value):
gevent.sleep(random.randint(0,2))
print 'Task', value, 'done', wid
def worker(wid):
while True:
item = q.get()
try:
print "Got item %s" % item
do_work(wid, item)
finally:
print "No more items"
q.task_done()
def producer():
while True:
item = random.randint(1, 11)
if item == 10:
print "Signal Received"
return
else:
print "Added item %s" % item
q.put(item)
for i in range(4):
workers.append(gevent.spawn(worker, random.randint(1, 100000)))
# This doesn't work.
for j in range(2):
producers.append(gevent.spawn(producer))
# Uncommenting this makes this script work.
# producer()
q.join()
này hoạt động tốt vì sleep
gọi là chặn cuộc gọi và khi một sự kiện xảy ra sleep
, một chủ đề màu xanh lá cây tiếp quản. Điều này nhanh hơn rất nhiều so với thực thi tuần tự. Như bạn có thể thấy, tôi không có bất kỳ mã nào trong chương trình của tôi cố tình tạo ra một chuỗi cho một luồng khác. Tôi không thấy cách này phù hợp với kịch bản ở trên như tôi muốn có tất cả các chủ đề thực hiện đồng thời.
Tất cả hoạt động tốt, nhưng tôi cảm thấy thông lượng mà tôi đã đạt được bằng cách sử dụng Gevent/Eventlets cao hơn chương trình chạy tuần tự ban đầu nhưng thấp hơn đáng kể so với những gì có thể đạt được bằng cách sử dụng luồng thực.
Nếu tôi thực hiện lại chương trình của mình bằng cách sử dụng cơ chế luồng, mỗi nhà sản xuất và người tiêu dùng của tôi có thể hoạt động đồng thời mà không cần trao đổi ngăn xếp trong và ngoài như coroutines.
Điều này có nên được triển khai lại bằng luồng không? Thiết kế của tôi có sai không? Tôi đã không nhìn thấy những lợi ích thực sự của việc sử dụng coroutines.
Có lẽ các khái niệm của tôi hơi lầy lội nhưng đây là những gì tôi đã đồng hóa. Bất kỳ sự giúp đỡ hoặc làm rõ về mô hình và khái niệm của tôi sẽ là tuyệt vời.
Cảm ơn
Tại sao không sử dụng nhiều quy trình? –
Tôi không biết ưu và nhược điểm của đa luồng so với đa xử lý vì vậy tôi không biết liệu nó có ổn hay không. –
không có thứ gì như "luồng thực" (chỉ có một chuỗi hệ điều hành thực hiện tại bất kỳ thời điểm nào) trong các chương trình Python mà không cần đến các phần mở rộng C (hoặc các quy trình OS nặng) vì Khóa thông dịch toàn cầu. –