Đối với tôi đây là thực sự khá đơn giản:
Các subprocess tùy chọn:
subprocess
là cho chạy file thực thi khác --- nó là cơ bản một wrapper xung quanh os.fork()
và os.execve()
với một số hỗ trợ cho các tùy chọn (Rõ ràng là các cơ chế truyền thông giữa các hệ điều hành (IPC) khác, chẳng hạn như ổ cắm, bộ nhớ chia sẻ SysV và hàng đợi tin nhắn có thể được sử dụng --- nhưng thường bạn đang sử dụng tiến trình con để chạy thứ ba bên nhị phân thực thi một d sẽ bị kẹt với bất kỳ giao diện nào và IPC hỗ trợ các kênh đó).
Thường sử dụng subprocess
đồng bộ --- chỉ cần gọi một số tiện ích bên ngoài và đọc lại kết quả hoặc chờ kết quả (có thể đọc kết quả từ tệp tạm thời hoặc sau khi đăng chúng lên cơ sở dữ liệu).
Tuy nhiên, người ta có thể sinh ra hàng trăm quy trình con và thăm dò ý kiến chúng. Tiện ích yêu thích cá nhân của riêng tôi thực hiện chính xác điều đó. Bất lợi lớn nhất của mô-đun subprocess
là hỗ trợ I/O thường chặn. Có một bản nháp PEP-3145 để khắc phục điều đó trong một số phiên bản tương lai của Python 3.x và một thay thế asyncproc (Cảnh báo dẫn đến tải xuống, không phải bất kỳ loại tài liệu nào cũng như README). Tôi cũng thấy rằng chỉ cần nhập fcntl
và thao tác trực tiếp các mô tả tệp PIPE Popen
PIPE của bạn --- mặc dù tôi không biết liệu đây có phải là phần mềm di động cho nền tảng không phải UNIX hay không.
subprocess
hầu như không có sự kiện xử lý hỗ trợ ... dù bạn có thể sử dụng các mô-đun signal
và đồng bằng cũ-trường tín hiệu UNIX/Linux --- giết chết quá trình của bạn nhẹ nhàng, như nó được.
Các đa tùy chọn:
multiprocessing
là để chạy chức năng trong hiện tại của bạn (Python) mã với sự hỗ trợ cho truyền thông linh hoạt hơn trong các gia đình của các quá trình. Đặc biệt, tốt nhất bạn nên tạo multiprocessing
IPC xung quanh các đối tượng của Queue
của mô-đun nếu có thể, nhưng bạn cũng có thể sử dụng các đối tượng Event
và nhiều tính năng khác (một số trong số đó có thể được hỗ trợ trên các nền tảng hỗ trợ đủ).
mô-đun multiprocessing
Python được thiết kế để cung cấp các giao diện và các tính năng mà rất tương tự nhưthreading
trong khi cho phép CPython quy mô xử lý của mình cho nhiều CPU/lõi bất chấp sự GIL (Global Interpreter Lock). Nó thúc đẩy tất cả các nỗ lực khóa và kết nối SMP hạt mịn được thực hiện bởi các nhà phát triển hạt nhân hệ điều hành của bạn.
Các luồng tùy chọn:
threading
là cho một phạm vi tương đối hẹp của các ứng dụng đó là I/O bound (không cần phải mở rộng trên nhiều lõi CPU) và được hưởng lợi từ các cực thấp độ trễ và chuyển đổi chi phí của chuyển đổi luồng (với bộ nhớ lõi được chia sẻ) so với chuyển đổi quy trình/ngữ cảnh. Trên Linux, đây gần như là bộ trống (thời gian chuyển đổi của quá trình Linux cực kỳ gần với các trình chuyển đổi luồng).
threading
bị hai nhược điểm chính trong Python.
Một, tất nhiên, là thực hiện cụ thể --- chủ yếu ảnh hưởng đến CPython. Đó là GIL. Đối với hầu hết các phần, hầu hết các chương trình CPython sẽ không được hưởng lợi từ sự sẵn có của nhiều hơn hai CPU (lõi) và thường hiệu suất sẽ bị từ GIL khóa ganh đua.
Vấn đề lớn hơn không thực hiện cụ thể, là các chủ đề chia sẻ cùng bộ nhớ, bộ xử lý tín hiệu, bộ mô tả tệp và một số tài nguyên hệ điều hành khác. Vì vậy, lập trình viên phải cực kỳ cẩn thận về khóa đối tượng, xử lý ngoại lệ và các khía cạnh khác của mã của chúng vừa tinh tế vừa có thể giết chết, ngăn chặn hoặc bế tắc toàn bộ quá trình (bộ chủ đề).
Bằng cách so sánh mô hình multiprocessing
cho mỗi quá trình bộ nhớ riêng, bộ mô tả tệp, v.v. Một ngoại lệ lỗi hoặc không được giải quyết trong bất kỳ một trong số chúng sẽ chỉ giết tài nguyên đó và xử lý mạnh mẽ sự biến mất của quá trình con hoặc anh chị em. dễ dàng hơn gỡ lỗi, cách ly và sửa chữa hoặc làm việc xung quanh các vấn đề tương tự trong chuỗi.
- (Lưu ý: sử dụng
threading
với các hệ thống Python lớn, chẳng hạn như NumPy, có thể vơi bớt khổ đau đáng kể từ GIL tranh sau đó hầu hết các mã Python của riêng bạn sẽ Đó là bởi vì họ đã được thiết kế đặc biệt để làm như vậy.).
Các xoắn tùy chọn:
Nó cũng đáng chú ý là Twisted cung cấp thêm một lựa chọn đó là cả thanh lịch và rất khó khăn để hiểu. Về cơ bản, với nguy cơ đơn giản hóa đến mức người hâm mộ của Twisted có thể xông vào nhà tôi với những cái chĩa và ngọn đuốc, Twisted cung cấp và phối hợp nhiều tác vụ theo sự kiện trong bất kỳ quá trình nào.
Để hiểu thế nào điều này có thể ta nên đọc về các tính năng của select()
(có thể được xây dựng xung quanh các chọn() hoặc cuộc thăm dò() hoặc tương tự hệ thống hệ điều hành các cuộc gọi). Về cơ bản, tất cả đều được thúc đẩy bởi khả năng đưa ra yêu cầu của hệ điều hành để ngủ trong khi chờ bất kỳ hoạt động nào trên danh sách các bộ mô tả tệp hoặc một số thời gian chờ.
Đánh thức từ mỗi cuộc gọi này đến select()
là sự kiện --- có thể có một số đầu cắm hoặc bộ mô tả tệp hoặc không gian đệm có sẵn trên một số bộ mô tả hoặc ổ cắm khác (có thể ghi) một số điều kiện đặc biệt (ví dụ như các gói PUSH'd out-of-band), hoặc một TIMEOUT.
Vì vậy, mô hình lập trình xoắn được xây dựng xung quanh việc xử lý các sự kiện này, sau đó lặp trên trình xử lý "chính", cho phép nó gửi các sự kiện tới trình xử lý của bạn.
Cá nhân tôi nghĩ rằng cái tên đó, Twisted như gợi nhiều liên tưởng của mô hình lập trình ... từ cách tiếp cận của mình vào vấn đề phải, trong một nghĩa nào đó, "xoắn" từ trong ra ngoài. Thay vì thụ thai chương trình của bạn như một loạt các hoạt động trên dữ liệu đầu vào và kết quả đầu ra hoặc kết quả, bạn đang viết chương trình của bạn như một dịch vụ hoặc daemon và xác định cách nó phản ứng với các sự kiện khác nhau. (Trong thực tế cốt lõi "vòng lặp chính" của một chương trình Twisted là (thường? Luôn?) Một reactor()
.
Các thách thức lớn cho việc sử dụng Twisted liên quan đến xoắn tâm trí của bạn xung quanh mô hình sự kiện thúc đẩy và cũng tránh sử dụng các Đây là lý do tại sao Twisted cung cấp các mô-đun riêng của mình để xử lý giao thức SSH, cho các lời nguyền, và các hàm xử lý con/popen của chính nó, và nhiều mô-đun và trình xử lý giao thức khác , lúc đầu đỏ mặt, dường như sẽ sao chép mọi thứ trong thư viện chuẩn của Python
Tôi nghĩ rằng hữu ích khi hiểu Twisted ở mức khái niệm ngay cả khi bạn không bao giờ định sử dụng nó. e thông tin chi tiết về hiệu suất, tranh chấp và xử lý sự kiện trong quá trình xử lý, xử lý đa xử lý và xử lý con cũng như bất kỳ quá trình xử lý phân tán nào mà bạn thực hiện.
(Lưu ý: phiên bản mới hơn của Python 3.x đã bao gồm asyncio (không đồng bộ I/O) tính năng như async def, các @ async.coroutine trang trí, và chờ từ khóa, và năng suất từ tương lai Hỗ trợ. Tất cả đều tương tự như Xoắn từ phối cảnh quá trình (phối hợp đa tác vụ)).
Các phân phối tùy chọn:
Tuy nhiên, một lĩnh vực chế biến bạn chưa được hỏi về, nhưng đó là giá trị xem xét, đó là của phân phối chế biến. Có nhiều công cụ và khung công tác Python để xử lý phân tán và tính toán song song. Cá nhân tôi cho rằng cách dễ nhất để sử dụng là điều ít được coi là thường xuyên nhất trong không gian đó.
Nó gần như là tầm thường để xây dựng xử lý phân tán xung quanh Redis. Toàn bộ kho khóa có thể được sử dụng để lưu trữ các đơn vị công việc và kết quả, Redis LIST có thể được sử dụng như Queue()
như đối tượng và hỗ trợ PUB/SUB có thể được sử dụng để xử lý giống như Event
. Bạn có thể băm khóa và sử dụng các giá trị của bạn, được sao chép trên một nhóm các trường hợp Redis, để lưu trữ cấu trúc liên kết và ánh xạ mã thông báo băm để cung cấp băm đồng nhất và thất bại cho việc mở rộng vượt quá khả năng của bất kỳ cá thể đơn lẻ nào để phối hợp công nhân của bạn và dữ liệu marshaling (ngâm, JSON, BSON hoặc YAML) trong số đó.
Tất nhiên khi bạn bắt đầu để xây dựng một quy mô lớn hơn và giải pháp phức tạp hơn xung quanh Redis bạn lại thực hiện rất nhiều các tính năng đã được giải quyết bằng, Celery, Apache Spark và Hadoop, Zookeeper, etcd, Cassandra và vân vân . Những alll đó có các mô-đun để truy cập Python vào các dịch vụ của chúng.
[Cập nhật: Một vài tài nguyên để xem xét nếu bạn đang xem xét Python để tính toán chuyên sâu trên các hệ thống phân tán: IPython Parallel và PySpark. Mặc dù đây là những hệ thống tính toán phân tán theo mục đích chung, chúng là các phân tích và phân tích dữ liệu hệ thống con đặc biệt có thể truy cập và phổ biến].
Kết luận
Ở đó bạn có gam màu của các lựa chọn thay thế chế biến cho Python, từ ren duy nhất, với các cuộc gọi đơn giản để đồng bộ quy trình con, vũng subprocesses thăm dò, luồng và đa, hướng sự kiện hợp tác đa nhiệm vụ, và ra để xử lý phân tán.
Liên quan: http://stackoverflow.com/questions/1743293/why-does-my-python-program-average-only-33-cpu-per-process-how-can-i-make-pytho/1743312 # 1743312 (đọc câu trả lời của tôi ở đó để xem lý do tại sao chủ đề là không khởi động cho mã thuần-Python) –
"Bất kỳ phiên bản Python" là FAR quá mơ hồ. Python 2.3? 1.x? 3.x? Nó chỉ đơn giản là một điều kiện không thể thỏa mãn. – detly