2012-02-19 2 views
1

저는 파이썬에 대한 실험을하고 싶었습니다. 자바 스크립트의 setTimeout 또는 setInterval과 같은 기능을 소개하고 이벤트 루프를 시작하기 위해 많은 블로킹 호출없이 비동기 동작을 포팅하고 싶습니다. C 모듈로 python GIL을 우회 할 수 있습니까?

는의가 (지금은 물론 작동하지 않는)이 예를 보자 :

from mymod import set_timeout # of course we love the PEP8 :) 
import sys, time 

def say_finished(): 
    time.sleep(2) # waiting, suppose here to have some blocking behaviour 
    sys.stdout.write("\nSee you!") 

sys.stdout.write("Hello, ") 
set_timeout(say_finished, 2000) # supposing we have msec granularity 
sys.stdout.write("World!") 

나는 자바 스크립트가하는 같은 동작을하고 싶습니다. set_timeout이 GIL로 인해 새 스레드를 시작한 경우 새로운 스레드가 완료 될 때까지 새 스레드가 차단되므로 "Hello, \ nSee you! World"가 여전히 인쇄됩니다.

set_timeout이 C 코드에서 posix 스레드를 사용하면이 동작을 피할 수 있습니까? 파이썬 C/API와의 통합이 될 것입니다. GIL을 우회 할 수 있는지 또는 API 자체가 GIL에 의해 차단되어야하는지 여부는 알지 못합니다.하지만 지금은 공부하고 있습니다. 워드 프로세서와 나는 그것을 스스로 시험해 볼 준비가되어 있지 않다).

다음과 같아야합니다 : "안녕하세요"-> set_timeout을 실행하십시오 (프로그램 실행을 계속하기 위해 돌아 가야합니다) -> "World!" -> 외부 스레드가 실행되는 동안 살아 남기 -> 콜백 "say_finished"-> 끝.

인터프리터 자체를 편집해야한다고 생각하는 이유는 "외부 스레드가 실행 중일 때 살아 있어야한다"는 부분입니다.

새 프로세스에서 생성하는 오버 헤드로 인해 프로세스를 사용하고 싶지 않습니다.

파이썬 구문이 좋기 때문에 "자바 스크립트 사용"이라고 말하지 마십시오.이 방법을 사용하고 싶습니다.

+0

당신이 묘사하는 것은 거의 정확히'threading.Timer'입니다. http://docs.python.org/library/threading.html#timer-objects –

답변

2

나는 GIL에 대해 혼란스러워한다고 생각합니다. 이것은 실행중인 모든 스레드간에 주기적으로 스왑하여 코드가 스레드로부터 안전함을 보장하는 VM의 구현 세부 사항입니다. 모든 VM은 스레드 안전을 보장 할 수있는 방법이 필요하며 GIL이 반드시 가장 빠르고 가장 좋은 구현은 아니지만 응용 프로그램 프로그래머가 걱정할 필요가있는 것은 아닙니다.

threading 모듈을 사용하면 둘 이상의 스레드에서 코드를 실행할 수 있습니다. 또는 "적절한"병렬성을 실제로 원할 경우 multiprocessing 모듈을 사용하여 별도의 OS 프로세스에서 코드를 실행하고 "GIL을 우회"합니다. 그것은 가치가있다. 특별히 비동기식을 원하면이 종류의 것을 제공하는 새로운 futures 모듈이 있습니다. 실제로 에 잠깐 동안가 필요하면 time.sleep으로 전화하십시오.

어느 쪽이든, 고수준의 것을 고수하고 따라서 자신의 응용 프로그램 특정 타이밍 및 일정을 잡으려고 시도하는 것보다 오류가 발생하기 쉽지 않습니다. 해결해야 할 간단한 문제가 아닙니다!

+0

GIL은 단 하나의 스레드 *가 한 번에 * 실행되도록합니다. 그래서'threading'을 사용하여 위의 코드를 실행하면 모든 스레드를 2 초 동안 차단합니다. 나는 다중 처리가 트릭을 할 것이지만 나는 위에서 말했듯이 그것을 피하고 싶다. 물론 완전한 스케줄러는 너무 많은 작업을해야 할 일이었고, 목적에 맞는 스레딩을 할 생각이었습니다. posix 스레드를 사용하여 카운터를 실행하면 만료 될 때 주 스레드를 차단하지 않고 "say_finished"를 호출합니다. –

+0

예제에서 'time.sleep'은 비동기 스레드 실행을 차단하는 CPU를 많이 사용하는 작업을 에뮬레이트하기위한 것입니다. –

+0

'시간.sleep()'은 실행중인 스레드 만 차단합니다. GIL을 해제하므로 다른 스레드가 실행될 수 있습니다. CPU를 많이 사용하는 작업이 C 언어 인 경우 GIL도 해제 할 수 있습니다. 파이썬에 있다면 두 스레드가 계속 실행되지만 별도의 코어에 배치하는 대신 두 스레드가 전환됩니다. –

관련 문제