bfiber_0100
Boost.Fiber Overview 개요
Overview 개요
Boost.Fiber는 협력적으로 예약된 마이크로/사용자영역(userland)-스레드(파이버)를 위한 프레임워크를 제공합니다.
API에는 표준 스레드 지원 라이브러리와 유사하게 파이버(fiber)를 관리하고 동기화하는 클래스와 기능(함수)이 포함되어 있습니다.
각 파이버에는 자체 스택이 있습니다. Each fiber has its own stack.
파이버(fiber)는 모든 레지스터 및 CPU 플래그, 명령 포인터 및 스택 포인터를 포함하여 현재 실행 상태를 저장하고 나중에 이 상태를 복원할 수 있습니다.
아이디어는 협력적(cooperative) 스케줄링을 사용하여 단일 스레드에서 여러 실행 경로를 실행하는 것입니다
(선제적으로(preemptively) 스케줄링되는 스레드에 비해).
실행 중인 파이버는 다른 파이버 실행을 허용하기 위해 언제 양보(yield)해야 하는지 명시적으로 결정합니다(컨텍스트 전환).
Boost.Fiber는 내부적으로 Boost.Context의 call/cc를 사용합니다.
이 라이브러리의 클래스는 해당 실행 컨텍스트를 관리하고 예약하며 필요한 경우 동기화합니다.
스레드 간 컨텍스트 전환은 일반적으로 100사이클 미만의 파이버 스위치와 비교하여 x86에서 수천 CPU 사이클의 비용이 듭니다.
파이버는 언제든지 단일 스레드에서 실행됩니다.
여기에 설명된 클래스 및 함수를 사용하려면, 각 클래스 또는 함수의 설명에 지정된 특정 헤더를 포함하거나
마스터 라이브러리 헤더를 포함할 수 있습니다.
여기에는 다른 모든 헤더가 차례로 포함됩니다.
사용되는 네임스페이스는 다음과 같습니다.
파이버와 스레드 - Fibers and Threads
특정 스레드에서 시작된 파이버 간에 제어가 협력적으로 전달됩니다.
주어진 순간, 주어진 스레드에서 최대 하나의 파이버가 실행 중입니다.
특정 스레드에서 추가 파이버를 생성(spawning)한다고 해서 프로그램이 더 많은 하드웨어 코어에 배포되는 것은 아니지만
실행 중인 코어를 보다 효과적으로 사용할 수 있습니다.
반면, 파이버는 동일한 스레드에서 다른 파이버의 동시 액세스로부터 해당 리소스를 명시적으로 방어할 필요 없이
상위 스레드가 독점적으로 소유한 리소스에 안전하게 액세스할 수 있습니다.
해당 스레드의 다른 파이버가 해당 리소스에 동시에 닿지 않는다는 것이 이미 보장됩니다.
이는 레거시 코드에 동시성을 도입할 때 특히 중요할 수 있습니다.
비동기 I/O를 사용하여 실행을 인터리브(interleave)함으로써 이전(old) 코드를 실행하는 파이버를 안전하게 생성할 수 있습니다.
실제로 파이버는 비동기 I/O를 기반으로 동시 코드를 구성하는 자연스러운 방법을 제공합니다.
완료 핸들러를 함께 연결하는 대신 파이버에서 실행되는 코드는 일반적인 차단 함수 호출처럼 보이는 것을 만들 수 있습니다.
해당 호출은 호출 파이버를 저렴하게(cheaply) 일시 중단하여 동일한 스레드의 다른 파이버가 실행되도록 할 수 있습니다.
작업이 완료되면 상태를 명시적으로 저장하거나 복원할 필요 없이 일시 중지된 파이버가 재개(resume)됩니다.
해당 로컬 스택 변수는 호출 전반(across)에 걸쳐 유지됩니다.
파이버는 한 스레드에서 다른 스레드로 마이그레이션될 수 있지만 라이브러리는 기본적으로 이를 수행하지 않습니다.
스레드 간에 파이버를 마이그레이션하는 사용자 정의 스케줄러를 제공할 수 있습니다.
스케줄러가 마이그레이션이 허용되는 파이버를 결정하는 데 도움이 되도록 사용자 정의 파이버 속성을 지정할 수 있습니다.
자세한 내용은 스레드 간 파이버 마이그레이션 및 사용자 정의를 참조하세요.
https://www.boost.org/doc/libs/1_85_0/libs/fiber/doc/html/fiber/migration.html#migration
https://www.boost.org/doc/libs/1_85_0/libs/fiber/doc/html/fiber/custom.html#custom
Boost.Fiber를 사용하면 여러 코어에 걸쳐 파이버를 다중화할 수 있습니다(numa::work_stealing 참조).
https://www.boost.org/doc/libs/1_85_0/libs/fiber/doc/html/fiber/numa.html#class_numa_work_stealing
특정 스레드에서 시작된 파이버는 마이그레이션되지 않는 한 해당 스레드에서 계속 실행됩니다.
다른 스레드에 의해 차단이 해제될 수 있지만(아래 Blocking 차단 참조) 현재 스레드의 파이버가 "차단됨(blocked)"에서
"준비(ready)"로 전환될 뿐입니다.
파이버가 차단 해제된 스레드에서 다시 시작되지는 않습니다.
스레드 로컬 저장소 - thread-local storage
마이그레이션하지 않는 한 파이버는 스레드 로컬 저장소에 액세스할 수 있습니다.
그러나 해당 저장소는 동일한 스레드에서 실행되는 모든 파이버 간에 공유됩니다.
파이버 로컬 스토리지에 대해서는 'Fiber_Specific_ptr'을 참조하세요.
https://www.boost.org/doc/libs/1_85_0/libs/fiber/doc/html/fiber/fls.html#class_fiber_specific_ptr
BOOST_FIBERS_NO_ATOMICS
이 라이브러리에서 제공하는 파이버 동기화 개체는 기본적으로 다른 스레드에서 실행되는 파이버를 안전하게 동기화합니다.
그러나 'BOOST_FIBERS_NO_ATOMICS'를 정의하여 라이브러리를 빌드하면 성능을 위해 이 동기화 수준을 제거할 수 있습니다.
해당 매크로를 사용하여 라이브러리를 구축할 때, 특정 동기화 개체를 참조하는 모든 파이버가 동일한 스레드에서 실행되고 있는지 확인해야 합니다.
동기화(Synchronization)를 참조하세요.
https://www.boost.org/doc/libs/1_85_0/libs/fiber/doc/html/fiber/synchronization.html#synchronization
차단 - Blocking
일반적으로 이 문서에 특정 파이버 블록(blocks)(또는 이와 동등하게 일시 중지(suspends))이 명시되어 있으면
이는 동일한 스레드의 다른 파이버가 실행될 수 있도록 제어할 수 있음을 의미합니다.
Boost.Fiber에서 제공하는 동기화 메커니즘에는 이러한 동작이 있습니다.
물론 파이버는 일반적인 스레드 동기화 메커니즘을 사용할 수 있습니다.
그러나 이러한 메커니즘 중 하나를 호출하는 파이버는 전체 스레드를 차단하여 그 동안 해당 스레드에서 다른 파이버가 실행되는 것을 막습니다.
예를 들어 파이버가 동일한 스레드에 있는 다른 파이버의 값을 기다리고 싶을 때 'std::future'를 사용하는 것은 불행한(unfortunate) 일입니다.
std::future::get()은 전체 스레드를 차단하여 다른 파이버가 그 값을 전달하는 것을 막습니다.
대신 future<>를 사용하세요.
마찬가지로 일반 차단 I/O 작업을 호출하는 파이버는 전체 스레드를 차단합니다.
Fiber 작성자는 비동기 I/O를 지속적으로 사용하는 것이 좋습니다.
Boost.Asio 및 기타 비동기 I/O 작업은 Boost.Fiber에 맞게 직접(straightforwardly) 조정할 수 있습니다.
비동기 콜백과 Fiber 통합을 참조하세요. Integrating Fibers with Asynchronous Callbacks.
https://www.boost.org/doc/libs/1_85_0/libs/fiber/doc/html/fiber/callbacks.html#callbacks
Boost.Fiber는 Boost.Context에 의존합니다. Boost 버전 1.61.0 이상이 필요합니다.
• Note
이 라이브러리에는 C++11이 필요합니다! This library requires C++11!
• Important
fcontext_t를 사용하는 Windows: 전역 프로그램 최적화(/GL)를 끄고 /EHsc를 /EHs로 변경합니다.
EHsc: 컴파일러는 extern "C"로 선언된 함수가 C++ 예외를 발생시키지 않는다고 가정합니다.
EHs: 컴파일러는 extern "C"로 선언된 함수가 예외를 던질 수 있다고 가정합니다.