>백엔드 개발 >파이썬 튜토리얼 >Python Greenlet 구현 메커니즘

Python Greenlet 구현 메커니즘

巴扎黑
巴扎黑원래의
2016-12-09 14:45:471262검색

최근에는 Python을 사용하여 웹 프로그램을 개발하고 있으며 항상 fastcgi 모드를 사용하고 있습니다. 그런 다음 요청 처리를 위해 각 프로세스에서 여러 스레드가 시작됩니다. 여기서 한 가지 문제는 각 요청의 응답 시간을 보장해야 한다는 것입니다. 매우 짧습니다. 그렇지 않으면 요청이 너무 느린 경우 어떤 스레드도 요청에 응답할 수 없기 때문에 서버는 서비스를 거부합니다. 일반적으로 우리 서비스는 온라인 상태가 되면 성능 테스트를 거치므로 정상적인 경우에는 큰 문제가 없습니다. 하지만 모든 시나리오를 테스트하는 것은 불가능합니다. 일단 나타나면 사용자가 응답하지 않고 오랜 시간을 기다려야 합니다. 그래서 일부 부분을 사용할 수 없게 되어 나중에 Python에서 코루틴과 그린렛으로 전환했습니다. 저는 그 구현 메커니즘을 간단하게 이해하고 있습니다.
각 Greenlet은 . >

typedef struct _greenlet {
PyObject_HEAD
char* stack_start;
char* stack_stop;
char* stack_copy;
intptr_t stack_saved;
struct _greenlet* stack_prev;
struct _greenlet* parent;
PyObject* run_info;
struct _frame* top_frame;
int recursion_depth;
PyObject* weakreflist;
PyObject* exc_type;
PyObject* exc_value;
PyObject* exc_traceback;
PyObject* dict;
} PyGreenlet;
각 Greenlet은 실제로 함수이며 이 함수가 실행될 때 정보를 저장합니다. 함수의 경우 컨텍스트는 동일한 프로세스의 모든 Greenlet이 할당한 공통 사용자 스택을 공유합니다. 따라서 충돌하지 않는 스택 데이터가 있는 Greenlet만 이 글로벌 스택을 동시에 사용할 수 있습니다. 현재 스택에 있는 Greenlet의 경우, 겹쳐진 Greenlet의 스택 데이터를 힙에 임시 저장해야 하며, 저장된 위치는 stack_copy 및 stack_saved를 통해 기록되므로 스택의 stack_stop 및 stack_start 위치를 힙 백에서 복사할 수 있습니다. 그렇지 않으면 스택 데이터가 파괴됩니다. 따라서 애플리케이션에서 생성된 이러한 그린렛은 데이터를 힙에 지속적으로 복사하거나 힙에서 스택으로 복사하는 방식으로 IO에 코루틴을 사용하는 것이 정말 편리합니다. -type 애플리케이션.


다음은 greenlet.c의 간단한 스택 공간 모델입니다.

A PyGreenlet is a range of C stack addresses that must be
saved and restored in such a way that the full range of the
stack contains valid data when we switch to it.
Stack layout for a greenlet:
               |     ^^^       |
               |  older data   |
               |               |
  stack_stop . |_______________|
        .      |               |
        .      | greenlet data |
        .      |   in stack    |
        .    * |_______________| . .  _____________  stack_copy + stack_saved
        .      |               |     |             |
        .      |     data      |     |greenlet data|
        .      |   unrelated   |     |    saved    |
        .      |      to       |     |   in heap   |
 stack_start . |     this      | . . |_____________| stack_copy
               |   greenlet    |
               |               |
               |  newer data   |
               |     vvv       |
다음은 간단한 greenlet 코드입니다.

from greenlet import greenlet
def test1():
    print 12
    gr2.switch()
    print 34
def test2():
    print 56
    gr1.switch()
    print 78
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
이전 기사:단축 URL 생성 변환다음 기사:단축 URL 생성 변환