메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

한빛랩스 - 지식에 가능성을 머지하다 / 강의 콘텐츠 무료로 수강하시고 피드백을 남겨주세요. ▶︎

IT/모바일

스택리스 파이썬 다시 태어나다!

한빛미디어

|

2002-05-02

|

by HANBIT

10,293

저자: 스티브 피긴스(Stephen Figgins), 역 전순재

스택리스 파이썬이 파이썬에 가한 변경은 논쟁의 대상이었다. 스택리스 파이썬은 파이썬의 실행 스택을 C의 실행스택, 즉 C-스택(C-stack)에서 분리하였다. 스택리스 파이썬을 사용하면 다중 실행 사슬을 설정할 수 있을 뿐만 아니라 그 사슬들 사이를 전환, 변경할 수 있으며 재시작 시킬 수도 있다. C-스택으로부터 해방되었으므로 파이썬 프로그램의 제어 흐름을 포착하여 원하는 대로 조작할 수 있다.

실행 스택을 조작하는 것은 컨티뉴에이션(continuation)[1] 뒤에 숨겨진 기본 개념으로 난해하지만 강력한 프로그래밍 구조에 많이 사용되는 빌딩블록이다. 파이썬이 작성된 대로라면 파이썬이 가진 실행 프레임이 C 스택에 직접 연결되어 있기 때문에 쉽게 실행 스택을 조작할 수는 없다. C 스택에 묶여 있기 때문에 파이썬은 실행 사슬을 완전하게 제어하지는 못한다. 또 C 스택은 재귀에도 제한을 준다. 스택에 여유가 있을 때까지의 깊이만큼만 재귀할 수 있을 뿐이다.

필자가 이전에 쓴 「스택리스 파이썬 개선 제안」이라는 기서에서처럼 스택리스 파이썬의 개발자인 크리스찬 디스머(Christian Tismer)는 스택리스 파이썬이 파이썬의 코어의 한 부분으로 받아들여지기를 희망했다. 그리고 바로 그 점이 논쟁의 중심이었다. 파이썬은 간결성에 초점을 두고 있기 때문에 어떤 사람들은 그렇게 강력한 테크닉은 파이썬에 어울리지 않는다고 생각했다. 디스머(Tismer)가 변경한 부분은 Jython과도 잘 작동하지 않는 경향이 있었다. 이러한 변경은 매우 신비로웠고 극소수만이 그것을 이해했으며 아무도 유지보수 하려고 하지 않았다. 따라서 스택리스 파이썬을 유지보수 하는 일은 디스머에게 도전이었다. 부분적으로는 그 이유가 스택리스 파이썬이 파이썬의 코어에 들어가기를 원했기 때문이었다. 스택리스 파이썬 지지자들은 일부에서는 저항이 있기는 하겠지만 스택리스 파이썬이 받아들여질 것이라고 추측했다. 파이썬 로드맵의 필자인 카메론 레어드(Cameron Laird)는 파이썬 버전 2.1이 나올 때 쯤에는 스택리스 파이썬이 실현될 것이라고 예언했다. 그러나 그러한 일은 일어나지 않았다.

디스머는 자신이 코어 개발자 그룹에게 파이썬을 완전히 다시 디자인해야 한다는 것을 확신시키기 위해 노력했으며 이와 같은 방식으로 파이썬이 불건전한 쌍으로 존재하는 것을 제거하기 위해 노력했다고 말했다. 그리고 다음과 같은 말도 덧붙였다. "파이썬 스택은 사슬처럼 연결된 프레임이다. 이 때문에 프레임 사이를 전환할 수 있다고 쉽게 믿게 된다. 그러나 C 스택이 내포된 모든 파이썬 프레임을 흉내내면서 거대한 바위처럼 버티고 서있었다. 그 때문에 전환이 불가능했다. 그렇지만 이제는 아니다. 나는 악을 선으로 다시 돌려 놓았다 그리고 금단의 일을 저질렀다."

케이크 한 조각을 입에 물고 수 많은 커피 잔을 들이키면서 미래를 생각해보았다. 디스머는 자신의 옛 코드를 포기하고 파이썬 코어에 받아들여지기를 원했던 모든 희망을 버리기로 결심했다. 대신에 그는 C-스택 그 자체를 다루기로 결심하였다. 스택리리스 파이썬이 나오기 전인 1999년, 샘 러싱(Sam Rushing)은 C-스택으로 직접적으로 전환하는 코루틴[2] 패키지를 만들었다. 파이썬 개발자들은 이것이 파이썬 코어에 절대로 허용되지 않을 것이라고 동의하였다. 샘 러싱의 루틴은 이식하기가 아주 어려웠을 것이다. 모든 플랫폼과 컴파일러가 C-스택을 서로 다르게 다루고 있기 때문이다. 파이썬의 일부분이 되기 위해 C-스택을 조작하는 것은 금지되었다. 디스머가 불가능에 도전한 결과 스택리스 코드는 난해하게 되었다. 여기서 말하는 디스머의 불가능한 도전이란 파이썬을 재작성할 필요 없이 그리고 C-스택 그 자체를 전혀 건드리지 않고서도 컨티뉴에이션을 파이썬 안에서 작동시키는 것이었다. 그렇지만 결과적으로 스택리스 파이썬은 어떠한 방식으로든 파이썬 코어안으로 들어가는데 실패했다. "스택리스 파이썬은 죽었다. 스택리스여 영원하라!"

접근방식을 다시 새롭게 하여 디스머는 eval_frame 함수를 가로채서, 래퍼(wrapper) 함수로 흐름을 돌린다. eval_frame을 최초로 호출하면, 현재의 C-스택 정지점은 약간의 어셈블리 코드를 사용하여 저장된다. 이 정지점은 이후의 모든 호출에 대한 참조점이 되어 그 어셈블리 코드는 스택으로 오고 거기서 복사된다. 그 어셈블리 코드는 스택이 너무 커지면 스택의 일부를 몰아내거나 또는 다른 마이크로스레드 또는 코루틴에 복사됨으로써 그 스택의 크기를 조정한다. 코어 파이썬 코드에서는 이 모든 것을 볼 수 없다. 코어 파이썬은 단지 자료들을 평소때와 같이 스택에 눌러넣고 튀겨꺼낼 뿐이며 정확하게 어떻게 스택이 배후에서 조작되고 있는지 전혀 알 필요가 없기 때문이다.

파이썬에 대한 변경은 극히 일부분에서만 일어나며 변화의 대부분은 파이썬이나 스택리스 파이썬이 변경될 때 변경할 필요가 없는 마크로에 대한 변경이다. 변경된 마크로의 내용들은 stackless.h 파일 하나에 모두 유지되므로 디스머가 쉽게 유지할 수 있다. 그렇지만 그 어셈블리 코드는 플랫폼에 의존하며 각각의 플랫폼에 대하여 일일이 손으로 코딩되어야 한다. 디스머는 마이크로소프트 윈도우에 맞는 어셈블리 코드를 만들었다. 그리고 gcc에 맞게 약간의 구문만 변경하면 인텔머신 기반의 리눅스에서도 틀림없이 쉽게 어셈블리 코드를 만들 수 있을 것이라고 말한다. OS의 역할은 프로세서나 컴파일러만큼 크지 않다. 그렇지만 디스머는 다른 플랫폼으로 이식할 계획은 없다. 누군가 그에게 기계를 대여해주고 그가 일주일동안 작업한 대가를 지급하지 않는 한 말이다.

어떤 사람들은 스택리스 파이썬의 종말처럼 팜에서도 파이썬이 더 이상 사용되지 않게 될 수도 있다는 걱정을 한다. 팜은 메모리상의 한계 때문에 스택의 크기를 제한하는 것이 중요하다. 스택리스 파이썬은 지금까지 팜에서 파이썬 포트의 기반이 되어 왔다. 나는 디스머에게 새로운 접근법이 팜에도 작동할 것인지 물어 보았다. "훨씬 더 좋다고 말하고 싶습니다."라고 그는 대답했다. "나는 전체적인 스택 요구량을 2K 이하로 줄여서 스택리스 파이썬을 테스트했습니다. 새로운 테크닉은 또다른 하드웨어 스택으로 전환하지 않기 때문에 훌륭하다고 판명되었습니다. 새로운 테크닉은 기존의 스택을 단지 늘리고 줄일 뿐입니다. 마치 정상적인 C 함수가 항상 그러는 것처럼 말이지요." 그는 스택리스 파이썬의 팜 포트[3]가 작업중에 있다고 말한다.

현재 디스머는 stacklessmodule.c를 작성하는 흥미로운 작업에 더 많은 관심을 쏟고 있다. 이 모듈은 코루틴과 마이크로스레드[4]에 대한 기본적인 연산들을 정의할 것이다. 이제 파이썬은 제너레이터[5]를 가지고 있으므로 그는 제너레이터를 스택리스 파이썬에 재구현하지 않을 것이다. 그리고 당분간은 최초 클래스[6] 컨티뉴에이션을 지원하지 않을 것이다.

비록 플랫폼을 광범위하게 지원하지는 않지만 스택리스 파이썬의 재탄생은 대단히 기쁜 일이다. 재탄생된 스택리스 파이썬은 더 간결하고 더 강력하다. 스택리스 파이썬 코드는 단 한 번만 각 플랫폼에 대해 작성되며, 새로운 파이썬 버전에 맞추어 변경될 필요가 없다. 그리고 이제는 아무런 제한없이 스택리스 파이썬으로 C확장을 사용할 수 있다. 만약 여러분이 마이크로스레드나 코루틴이 필요하고 플랫폼이 지원된다면 스택리스 파이썬은 아름답고 새로운 날을 열어줄 것이다.
[1] 컨티뉴에이션(continuation): 실행을 중지했다가 재개할 수 있는 기능
[2] 코루틴(coroutine): 대등한 관계로 서로 호출가능한 루틴
[3] 포트(port): 각 장치에 적합하게 이식된 버전
[4] 마이크로스레드(microthread): 경량 스레드
[5] 제너레이터(generator): 발생자 - 실행상태를 보존한 상태에서 반환한다. 파이썬 2.2에서 상태 보존을 위해 yield 키워드가 새로 도입됨.
[6] 최초 클래스(first class): 함수에 대한 인수 또는 반환값으로 사용할 수 있는 객체
TAG :
댓글 입력
자료실

최근 본 상품0