Những gì bạn đang tìm kiếm là mô hình Nhà sản xuất / Người tiêu dùng
Ví dụ về luồng cơ bản
Đây là một ví dụ cơ bản sử dụng mô-đun phân luồng (thay vì đa xử lý)
import threading
import Queue
import sys
def do_work(in_queue, out_queue):
while True:
item = in_queue.get()
result = item
out_queue.put(result)
in_queue.task_done()
if __name__ == "__main__":
work = Queue.Queue()
results = Queue.Queue()
total = 20
for i in xrange(4):
t = threading.Thread(target=do_work, args=(work, results))
t.daemon = True
t.start()
for i in xrange(total):
work.put(i)
work.join()
for i in xrange(total):
print results.get()
sys.exit()
Bạn sẽ không chia sẻ đối tượng tệp với các chủ đề. Bạn sẽ tạo ra công việc cho họ bằng cách cung cấp hàng đợi với các dòng dữ liệu. Sau đó, mỗi luồng sẽ chọn một dòng, xử lý nó và sau đó trả lại nó trong hàng đợi.
Có một số tiện ích nâng cao hơn được tích hợp trong mô-đun đa xử lý để chia sẻ dữ liệu, như danh sách và loại Hàng đợi đặc biệt . Có sự đánh đổi khi sử dụng đa xử lý so với luồng và điều đó phụ thuộc vào việc công việc của bạn bị ràng buộc cpu hay IO.
Đa xử lý cơ bản. Ví dụ về công cụ
Đây là một ví dụ thực sự cơ bản về Nhóm đa xử lý
from multiprocessing import Pool
def process_line(line):
return "FOO: %s" % line
if __name__ == "__main__":
pool = Pool(4)
with open('file.txt') as source_file:
results = pool.map(process_line, source_file, 4)
print results
Pool là một đối tượng tiện lợi quản lý các quy trình của riêng nó. Vì một tệp đang mở có thể lặp qua các dòng của nó, bạn có thể chuyển nó đến tệp, tệp pool.map()
này sẽ lặp qua nó và cung cấp các dòng cho hàm worker. Bản đồ chặn và trả về toàn bộ kết quả khi hoàn thành. Hãy lưu ý rằng đây là một ví dụ quá đơn giản và pool.map()
sẽ đọc toàn bộ tệp của bạn vào bộ nhớ cùng một lúc trước khi xử lý công việc. Nếu bạn muốn có các tệp lớn, hãy ghi nhớ điều này. Có nhiều cách nâng cao hơn để thiết kế một nhà sản xuất / người tiêu dùng.
"Nhóm" thủ công với giới hạn và sắp xếp lại dòng
Đây là một ví dụ thủ công của Pool.map , nhưng thay vì sử dụng toàn bộ tệp có thể lặp lại trong một lần, bạn có thể đặt kích thước hàng đợi để bạn chỉ nạp từng phần một nhanh nhất có thể. Tôi cũng đã thêm số dòng để bạn có thể theo dõi chúng và tham khảo chúng nếu bạn muốn, sau này.
from multiprocessing import Process, Manager
import time
import itertools
def do_work(in_queue, out_list):
while True:
item = in_queue.get()
line_no, line = item
if line == None:
return
time.sleep(.5)
result = (line_no, line)
out_list.append(result)
if __name__ == "__main__":
num_workers = 4
manager = Manager()
results = manager.list()
work = manager.Queue(num_workers)
pool = []
for i in xrange(num_workers):
p = Process(target=do_work, args=(work, results))
p.start()
pool.append(p)
with open("source.txt") as f:
iters = itertools.chain(f, (None,)*num_workers)
for num_and_line in enumerate(iters):
work.put(num_and_line)
for p in pool:
p.join()
print sorted(results)