Tôi muốn biết cách xử lý đa được thực hiện đúng cách. Giả sử tôi có một danh sách [1,2,3,4,5]
được tạo bởi hàm f1
được ghi vào một số Queue
(vòng tròn màu xanh lá cây bên trái). Bây giờ tôi bắt đầu hai quá trình kéo từ hàng đợi đó (bằng cách thực hiện f2
trong các quy trình). Họ xử lý dữ liệu, giả sử: nhân đôi giá trị và ghi nó vào hàng đợi thứ hai. Bây giờ, hàm f3
đọc dữ liệu này và in ra.Đa xử lý trong một đường ống được thực hiện ngay
Bên trong các chức năng có một loại một vòng, cố gắng đọc từ hàng đợi mãi mãi. Làm thế nào để tôi ngừng quá trình này?
Idea 1
f1
không chỉ gửi danh sách, mà còn là một đối tượng None
hoặc một đối tượng custon, class PipelineTerminator: pass
hoặc một số ví dụ mà chỉ được tuyên truyền tất cả các con đường xuống. f3
bây giờ chờ None
để đến, khi nó ở đó, nó vỡ ra khỏi vòng lặp. Sự cố: có thể một trong hai số f2
s đọc và truyền bá số None
trong khi số khác vẫn xử lý một số. Sau đó, giá trị cuối cùng bị mất.
Idea 2
f3
là f1
. Vì vậy, chức năng f1
tạo ra dữ liệu và các đường ống, sinh ra các quy trình với f2
và cung cấp tất cả dữ liệu. Sau khi sinh sản và cho ăn, nó lắng nghe trên ống thứ hai, chỉ cần đếm và xử lý các đối tượng nhận được. Vì nó biết lượng dữ liệu được nạp, nó có thể chấm dứt các quá trình thực thi f2
. Nhưng nếu mục tiêu là để thiết lập một đường ống xử lý, các bước khác nhau nên được tách ra. Vì vậy, f1
, f2
và f3
là các thành phần khác nhau của một đường ống và các bước đắt tiền được thực hiện song song.
Idea 3
Mỗi mảnh của đường ống là một chức năng, chức năng này sinh ra các quy trình vì nó thích và có trách nhiệm để quản lý chúng. Nó biết, bao nhiêu dữ liệu đến và bao nhiêu dữ liệu đã được trả về (với yield
có thể). Vì vậy, nó an toàn để tuyên truyền một đối tượng None
.
setup child processes
execute thread one and two and wait until both finished
thread 1:
while True:
pull from input queue
if None: break and set finished_flag
else: push to queue1 and increment counter1
thread 2:
while True:
pull from queue2
increment counter2
yield result
if counter1 == counter2 and finished_flag: break
when both threads finished: kill process pool and return.
(Thay vì sử dụng chủ đề, có lẽ người ta có thể nghĩ ra một giải pháp thông minh hơn.)
Vậy ...
tôi đã thực hiện một giải pháp sau đây ý tưởng 2, cho ăn và chờ đợi kết quả đến, nhưng nó không thực sự là một đường ống với các chức năng độc lập được cắm vào nhau. Nó làm việc cho công việc tôi phải quản lý, nhưng rất khó để duy trì.
Tôi muốn nghe ý kiến của bạn về cách bạn triển khai đường ống (dễ dàng trong một quy trình với các chức năng của máy phát, v.v., nhưng với nhiều quy trình?) Và quản lý chúng thường xuyên.
Nhưng người lao động nên biết như thế nào trong 'f2' * biết * đó là người cuối cùng? 'f1' cần phải biết có bao nhiêu công nhân và gửi số đối tượng tùy chỉnh đó. Làm như vậy, đảm bảo rằng mọi nhân viên đều nhận được thông báo này. Điều đó rõ ràng là có thể, nhưng sau đó tôi không thể "chỉ cần cắm các chức năng", tôi cần phải biết có bao nhiêu công nhân ở mỗi bước. Đó là lý do tại sao tôi thích ý tưởng 3. Và cảm ơn bạn vì những thứ 'đồng thời', đó là điều mới mẻ đối với tôi và tôi sẽ đào sâu vào nó. –
Đó cũng là lý do tại sao tôi đã chọn "chấp nhận" :) –
Vì đối tượng tùy chỉnh "ngừng hoạt động" được gửi bởi "F1", nó có thể bao gồm tổng số quy trình công nhân "f2". Nếu những điều này chỉ truyền đối tượng "ngừng làm việc" tới "f3", nó sẽ biết tổng số người lao động. Thông tin chi tiết có thể được gửi theo cách này - vì vậy một điều quan trọng là phải có một "lớp điều khiển" ít nhất trong "f3" (nhưng cũng có thể trong "f1") mà sẽ chỉ lo lắng về điều này và chỉ truyền xuống bất kỳ "thông báo" không các đối tượng trên hàng đợi để thực sự được xử lý. – jsbueno