2017-12-03 7 views
1

나는 소켓에서 데이터를 가져 와서 처리하는 파이썬 C- 확장을 가지고있다. 처리 중에 GIL이 해제된다. 현재 필자는 GIL-release로 인해 2 개의 Python 스레드를 사용하여 2 개의 CPU 코어에 90 %의로드를 발생시킵니다.Asyncio from Python C- 확장자

파이썬 3 asyncio에서 어떻게 같은 결과를 얻을 수 있습니까? 올바른 Python-C-API 명령을 찾지 못했습니다. 이벤트 루프가 가서 다른 일을 할 수 있다고 알려줍니다.

다른 방법으로 말하자면, 내 확장 기능이 GIL을 해제하면 이는 자동으로 이벤트 루프에서 사용할 수있는 다음 항목의 실행을 차단하지 않는다는 뜻입니까? 예 : 내 C- 확장자가 첫 번째 소켓의 데이터를 처리하는 동안 다음 소켓을 읽을 수 있습니까? 이것은 어디서나 찾을 수 없습니다. 이 방법을 이해하면 많은 소켓에서 데이터를 가져와 더 많은 CPU 코어를 사용할 수 있습니다.

+0

작성된 것처럼 아주 좋은 질문은 아닙니다. 확장 프로그램이 이벤트 루프와 상호 작용하는 모습을보고 싶다면 스케치해야합니다. 설명했듯이 확장 프로그램이 이벤트 루프와 상호 작용해야하는 것처럼 들리지는 않습니다. –

+0

확장 및 이벤트 루프에 대해 원하는 상호 작용을 설명하는 의사 코드를 설명 할 수 있다면이를 수행하는 방법을 설명하는 것이 가능할 수 있습니다. –

+0

@ SamHartman 그럴 수도 있습니다. 제 질문은 주로 : 내 확장 기능이 GIL을 해제하면 자동으로 이벤트 루프에서 사용할 수있는 다음 항목의 실행을 차단하지 않는다는 의미입니까? 예. 내 C- 확장자가 첫 번째 소켓의 데이터를 처리하는 동안 다음 소켓을 읽을 수 있습니까? 이것은 어디서나 찾을 수 없습니다. – Safihre

답변

2

이벤트 루프 내에서 내선 번호가 호출되면 GIL을 해제해도 이벤트 루프가 계속되지는 않습니다.

async def process(): 
    call_your_extension() 

asyncio.get_event_loop.create_task(process()) 

다음 이벤트 루프가 계속 발생하지 않습니다 확장에 GIL을 발표 :이다

는, 내가 좋아하는 일을 말한다. 루틴은 동기식입니다.

대신, 반환 또는 어떤 종류의 awaitable을 만든 다음이 모델에서

async def process() 
    await call_your_extension() 

을 할 수있는, 확장은 아마도 __await__ 방법으로 클래스 될 것입니다. 결국 asyncio.futures.Future을 생성해야합니다. 이벤트 루프는 완료된 콜백을 해당 미래에 첨부하고 완료 콜백이 호출되면 process이 다시 시작될 수 있습니다. 아마 여러 코어를 사용하려는 무언가에 적합하지 않을 것입니다. 이벤트 루프는 하나의 스레드에서만 실행됩니다.

concurrent.futures을 사용하고 스레드를 통해 실행할 수있는 미래를 생성하여 어떤 이점을 얻을 수 있습니다. 그런 다음 asyncio.ensure_future을 사용하여 asyncio Future으로 변환 할 수 있습니다. 그러나이 모든 것은 이벤트 루프가 어떻게 든 확장에 이익이된다고 가정합니다. 소켓에서 독서를 내선에서 이벤트 루프 코드로 옮길 수 있다면 그럴 가능성이 높습니다. 그렇지 않으면 현재 디자인이 이상적 일 수 있습니다. 이벤트 루프 모델과 상호 운용해야하는 경우 asyncio.get_event_loop().run_in_executor