2011-10-25 7 views
1

루비 C 확장으로 간단한 윈도우 라이브러리를 구현하고 있습니다. Windows에는 handle_events! 메서드가있어 네이티브 이벤트 루프에 들어갑니다.루비 C 확장 : 동시에 이벤트 루프를 실행하십시오.

문제는 창당 하나의 이벤트 루프와 메소드 블록을 원한다는 것입니다. 메서드를 즉시 반환하고 루프가 별도의 스레드에서 실행되도록하고 싶습니다. 이것을 달성하는 가장 좋은 방법은 무엇입니까?

rb_thread_call_without_gvl을 사용하여 이벤트 루프 함수를 호출 한 다음 rb_thread_call_with_gvl을 사용하여 Proc 초의 콜백을 호출하려고했습니다. 전체 소스 코드는 here입니다.

여전히 작동하지만 의도했던대로 작동하지 않습니다.이 방법은 여전히 ​​차단됩니다. Ruby의 스레딩 모델에서도 이것이 가능합니까?

+0

[이]에 대한 답변입니다. [1] : http://stackoverflow.com/questions/56087/does-ruby-have-real-multithreading –

답변

0

나는 해결할 매우 동일한 문제가있었습니다. 그리고 1.9.2에서 rb_thread_call_with_gvl()이 실험적으로 표시되었지만 내 보낸 심볼이 아니기 때문에 다른 접근 방식을 택했습니다.

차단 handle_event! 함수를 별도의 스레드에서. 두 번째 루비 스레드를 사용하여 메시지 대기열에서 차단했습니다. 메시지 큐에서 블로킹하는 동안 rv_thread_blocking_region()으로 gvl이 릴리스되었습니다.

이제 handle_event! 이벤트로 인해 차단 해제되었으므로 대기열 요소에서 Proc의 upcall에 필요한 모든 정보를 함께 가져 와서 해당 요소를 대기열에 밀어 넣었습니다. 루비 스레드는 rb_thread_blocking_region()에서 반환 된 요소를 수신하여 gvl을 다시 획득하고 수신 된 요소의 정보로 Proc를 호출합니다.

종류는 rb_thread_call_with_gvl() 여전히 같은 스레드에서 일을해야 사용, 지금까지 내가 이해 스텐에게

0

을 간주한다. 즉, 스레드를 변경하는 것이 아니라 전역 잠금을 해제하고 가져 오는 것입니다. 예를 들어, 장기 실행 gzip 함수는 잠금없이 실행되어 다른 루비 스레드가 병렬로 실행될 수 있습니다.

Procs가 다른 스레드에서 다시 호출되기를 원하면 해당 Procs에 대해 루비 스레드를 만들지 않아도됩니까? 그런 다음 해당 스레드에서 rb_thread_call_without_gvl()을 호출하여 GVL을 보유하지 않고 (다른 루비 스레드를 실행할 수있게 함), 보조 창 스레드에서 이벤트가 발생하면 rb_thread_call_with_gvl()으로 전화를 걸어 잠금 장치를 호출해야합니다. 같은 스레드에 Proc. 내가 알고있는 방법이다

(매우 긴 C 확장 물건을 수행하는 데 없습니다.) [1] 질문 당신을 도울 수