Zettelkasten

greenlet의 동작 방식

·수정 2026.04.23·수정 2

요약

  • greenlet은 경량 스레드 일종으로 스택 기반의 context 전환을 사용해 실행 정보를 중간에 저장해 멈추고 다시 멈췄던 지점부터 다시 실행할 수 있다.

본문

  • greenlet: 스택 기반의 컨텍스트 전환을 구현한 경량 스레드

  • 경량 스레드: context switching 비용이 적은 실행 단위

  • greenlet 구현(경량화 스레드, green thread)

typedef struct _greenlet {
    PyObject_HEAD
    struct _greenlet* parent;
    void* stack_start;  
    void* stack_stop;
    void* stack_copy;
    intptr_t stack_saved;
    char* stack_prev;
    PyObject* run_info;
    PyObject* weakreflist;
    PyObject* dict;
    PyObject* context;
} PyGreenlet;
  • stack_start, stack_stop: 현재 스택 범위
  • stack_copy: 비활성화시 스택 백업 저장
  • parent: 전환 복귀 대상
  • run_info: 현재 실행중인 스레드 정보
작업 전환
static PyGreenlet* g_current;
int g_switch(PyGreenlet* target) {
    // 현재 스택 저장
    save_stack(g_current);
    
    // 대상 스택 복원
    restore_stack(target);

    g_current = target;
    return 0;
}

void save_stack(PyGreenlet* g) {
    char dummy;
    g->stack_stop = &dummy; # 현재 스택 포인터의 위치를 stack_stop에 저장
    size_t size = g->stack_start - g->stack_stop; # 현재 스택 크기
    g->stack_copy = malloc(size); # size 만큼 동적 할당
    memcpy(g->stack_copy, g->stack_stop, size); # 메모리 카피 상태 저장
    g->stack_saved = size;
}

void restore_stack(PyGreenlet* g) {
    memcpy(g->stack_stop, g->stack_copy, g->stack_saved);
}

왜 경량 스레드는 OS 스레드 보다 가볍지?

  • os 스레드는 아래와 같은 over head가 존재함
    1. 컨텍스트 전환(유저 모드 → 커널 모드 전환) 으로 인한 인터럽트
    2. 전체 레지스터, 커널 스택 저장 필요
    3. 캐시 손실
    4. 스케줄러 오버헤드