2010-05-30 27 views
19

Gói greenlet được sử dụng bởi gevent và eventlet cho IO không đồng bộ. Nó được viết dưới dạng phần mở rộng C và do đó không hoạt động với Jython hoặc IronPython. Nếu hiệu suất không quan tâm, cách tiếp cận dễ nhất để triển khai API greenlet bằng Python thuần túy là gì.Cài đặt python tinh khiết của API màu xanh lá cây

Một ví dụ đơn giản:

def test1(): 
    print 12 
    gr2.switch() 
    print 34 

def test2(): 
    print 56 
    gr1.switch() 
    print 78 

gr1 = greenlet(test1) 
gr2 = greenlet(test2) 
gr1.switch() 

nên in 12, 56, 34 (chứ không phải 78).

+0

IronPython và Jython chạy trên máy ảo đó là hoàn toàn ren và có riêng của họ async IO gọi - bạn sẽ không sử dụng những? – Mark

+0

Cuối cùng có, nhưng tôi đã suy nghĩ về việc viết một phiên bản python tinh khiết trước khi thêm các phiên bản VM cụ thể. Hình thức kiểm soát dòng chảy này không hoàn toàn trực quan. – Tristan

+0

Theo nhận xét về một trong các câu trả lời, mục tiêu cuối cùng của bạn là sử dụng 'eventlet' trong IronPython hoặc Jython. Điều đó sẽ không hoạt động — không phải vì 'greenlet', mà là vì 'libevent', một thư viện C mà' eventlet' kết thúc và phụ thuộc vào vòng lặp sự kiện và lò phản ứng của nó. Bạn có thể hình dung lại toàn bộ API 'libevent' trên đầu trang của vòng lặp .NET hoặc Java (ít nhất là nếu bạn không quan tâm đến hiệu suất, như bạn nói bạn không làm), nhưng đó là toàn bộ công việc. – abarnert

Trả lời

12

Loại điều này có thể đạt được với các đồng thường trình đã được tích hợp vào bản phân phối chuẩn Python kể từ phiên bản 2.5. Nếu IronPython và co hoàn toàn tuân thủ tất cả các tính năng của Python 2.5 (tôi tin là chúng), bạn sẽ có thể sử dụng thành ngữ này.

Xem this post để biết thêm thông tin về cách chúng có thể được sử dụng :) Cụ thể, bạn sẽ quan tâm đến PDF. .

Bạn cũng có thể muốn xem Gogen hoặc Kamelia cho ý tưởng: các dự án này đều có triển khai coroutine trăn thuần túy mà bạn có thể áp dụng hoặc sử dụng làm tham chiếu cho việc triển khai của riêng bạn. Hãy xem this page để có phần giới thiệu nhẹ nhàng về cách làm việc của cogen.

Lưu ý có một số khác biệt giữa việc triển khai đồng thường xuyên tại đây và triển khai greenlet. Việc triển khai python tinh khiết đều sử dụng một số loại lịch trình bên ngoài nhưng ý tưởng về cơ bản là giống nhau: chúng cung cấp cho bạn một cách để chạy các tác vụ hợp tác nhẹ mà không cần phải đề cập đến các chủ đề. Ngoài ra, cả hai khung công tác được liên kết ở trên đều hướng đến IO không đồng bộ rất giống với chính bản thân số greenlet.

Dưới đây là ví dụ bạn được đăng nhưng viết lại sử dụng cogen:

from cogen.core.coroutines import coroutine 
from cogen.core.schedulers import Scheduler 
from cogen.core import events 

@coroutine 
def test1(): 
    print 12 
    yield events.AddCoro(test2) 
    yield events.WaitForSignal(test1) 
    print 34 

@coroutine 
def test2(): 
    print 56 
    yield events.Signal(test1) 
    yield events.WaitForSignal(test2) 
    print 78 

sched = Scheduler() 
sched.add(test1) 
sched.run() 

>>> 12 
>>> 56 
>>> 34 

Đó là rõ ràng hơn một chút so với phiên bản greenlet (ví dụ sử dụng WaitForSignal để tạo ra một cách rõ ràng một điểm khôi phục) nhưng bạn sẽ nhận được các ý tưởng chung.

chỉnh sửa: Tôi chỉ khẳng định rằng công trình này sử dụng Jython

KidA% jython test.py 
12 
56 
34 
+0

tuyệt vời !! _ _ _ _ – mlvljr

+1

Đây là một ví dụ điển hình, tuy nhiên tôi thực sự thú vị khi sử dụng chính xác api greenlet mà không có báo cáo lợi nhuận. Tôi muốn kích hoạt eventlet, yêu cầu greenlet, trên Jython và IronPython. – Tristan

+0

@tristan: nếu bạn muốn mô phỏng một cái gì đó giống như greenlet, bạn sẽ phải thực hiện những ý tưởng này và bọc chúng trong một API giống hệt nhau. Nó sẽ có thể đến với một cái gì đó gần gũi. Tôi có thể có một chuyến đi và cho bạn thấy một cái gì đó như thế này nhưng tôi nghĩ rằng bạn cần phải mất những gì được hiển thị và chạy với nó! Rõ ràng greenlet chính nó là không có sẵn, nhưng điều này cho thấy rằng các nguyên tắc mang trên và có thể tái sử dụng. – jkp

10

Không thể triển khai greenlet bằng Python thuần túy.

UPDATE:

  • giả API greenlet với chủ đề có thể thực sự có thể làm được, ngay cả khi hoàn toàn vô dụng cho tất cả các mục đích thực tế
  • máy phát điện không thể được sử dụng cho điều này khi họ chỉ tiết kiệm nhà nước của một đơn khung. Greenlets lưu toàn bộ ngăn xếp. Điều này có nghĩa là gevent có thể sử dụng bất kỳ giao thức nào được triển khai trên đỉnh của socket chuẩn (ví dụ: các mô-đun httplib và urllib2). Các khung công tác dựa trên máy phát điện yêu cầu các máy phát điện trong tất cả các lớp của phần mềm của bạn, do đó, việc giải phóng và tấn các gói khác bị vứt bỏ.
+2

Tôi biết điều này là đúng, nhưng bạn có thể xây dựng trên * tại sao *? – Glyph

+4

Không thể hoặc không thực hiện được? Chúng tôi có thể giả mạo API greenlet với chủ đề không? – Tristan

+1

Thực ra, đó là một điểm thú vị. Có lẽ chúng ta thực sự có thể sử dụng API greenlet giả với các luồng. Tuy nhiên, nó không thực tế, như trong trường hợp đó gevent và eventlet sẽ cung cấp cho bạn API mà bạn đã có (như ổ cắm), chỉ với nhiều chi phí hơn. –

Các vấn đề liên quan