Boost.Fiber Sharing a Thread with Another Main Loop


Sharing a Thread with Another Main Loop

다른 메인 루프와 스레드 공유

📦 Overview - 개요

협력적 동시성(cooperative concurrency)과 마찬가지로 하나의 파이버가 프로세서를 너무 오랫동안 독점(monopolize)하지 않도록 하는 것이 중요합니다.   이는 다른 준비된 파이버를 "starve(굶주릴)" 수 있습니다.   이 섹션에서는 몇 가지 솔루션에 대해 설명합니다.

⚛ 원문

📦 Event-Driven Program - 이벤트 중심 프로그램

들어오는 I/O 이벤트를 가져오고((fetches)) 전달하는(dispatches) 메인 루프를 중심으로 구성된 고전적인 이벤트 중심(event-driven) 프로그램을 생각해 보세요.   Boost.Fiber를 도입하는 이유는 특정 비동기 I/O 시퀀스가 ​​논리적으로 순차적이고, 순차적으로 보이고 작동하는 코드를 작성하고 유지하기를 원하기 때문입니다.

특정 작업이 사용자 인터페이스에 영향을 미치고 애플리케이션의 UI 프레임워크가 메인 스레드에서만 UI 작업을 허용하기 때문에 애플리케이션의 메인 스레드에서 파이버를 시작합니다.   또는 해당 파이버는 메인 스레드 데이터에 액세스해야 하며 스레드 동기화 기본 요소를 사용하여 이러한 모든 데이터 항목을 강력하게 방어하는 것은 런타임(또는 개발 시간)에 너무 많은 비용이 듭니다.
⚛ 번역과 'primitives'에 대한 설명 (chatgpt)
    primitives: Mutex(뮤텍스), Semaphore(세마포어), Condition Variable(조건 변수), Spinlock(스핀락), 등

애플리케이션의 메인 루프 자체가 프로세서를 독점하지 않도록 해야 합니다.   그것이 시작하는 파이버는 필요한 CPU 사이클을 얻을 것입니다.

해결 방법은 장기간(extended time) CPU를 점유할(claim) 수 있는 파이버의 경우와 동일합니다.   this_fiber::yield()에 대한 호출을 도입합니다.   가장 간단한 접근 방식은 기존 메인 루프가 반복될 때마다 yield()를 호출하는 것입니다.   실제로 이는 애플리케이션의 메인 루프를 Boost.Fiber의 내부 메인 루프와 통합합니다.   yield()를 사용하면 파이버 관리자가 애플리케이션 메인 루프의 이전 반복(previous iteration) 이후 준비된 파이버를 실행할 수 있습니다.   이러한 파이버가 차례를 가지면 제어는 스레드의 메인 파이버로 전달되며, 이 파이버는 yield()에서 반환되어 애플리케이션의 메인 루프를 재개합니다.

⚛ 원문

📦 Embedded Main Loop - 내장 메인 루프

더 어려운 점은 애플리케이션의 메인 루프가 다른 라이브러리나 프레임워크에 내장되어 있을 때입니다.   이러한 응용 프로그램은 일반적으로 필요한 모든 설정을 수행한 후 응용 프로그램이 종료될 때까지 제어가 반환되지 않는 일부 형태의 run() 함수에 제어를 전달합니다.

Boost.Asio 프로그램은 이런 방식으로 io_service::run()을 호출할 수 있습니다.

일반적으로 비결은 this_fiber::yield()에 제어권을 자주 전달하도록 준비하는 것입니다.   그 목적으로 Asio 타이머를 사용할 수 있습니다.   타이머가 만료될 때 처리기 함수를 호출하도록 배열하여 타이머를 인스턴스화할 수 있습니다.   핸들러 함수는 yield()를 호출한 다음 타이머를 재설정하고 다음 만료 시 다시 깨어나도록 준비할 수 있습니다.

이 사고 실험(thought experiment)에서는 항상 yield()을 통해 파이버 관리자에게 제어권을 전달하므로 호출 파이버는 차단되지 않습니다.   따라서 항상 준비된 파이버가 하나 이상 있습니다.   따라서 파이버 관리자는 algorithm::suspend_until()을 호출하지 않습니다.

0이 아닌(nonzero) 간격으로 타이머를 설정하는 대신 io_service::post()를 사용하는 것은 다른 스레드에 친숙하지 않습니다.   모든 I/O가 보류 중이고 모든 파이버가 차단되면 'io_service'와 파이버 관리자는 단순히 CPU를 회전(spin)시켜 제어권을 서로 주고받습니다.   타이머를 사용하면 다른 스레드에 비해 이 스레드의 응답성을 조정할 수 있습니다.

⚛ 원문

📦 Deeper Dive into Boost.Asio - Boost.Asio에 대해 자세히 알아보기

⚛ 원문


Email 답글이 올라오면 이메일로 알려드리겠습니다.