bfiber_0300
Boost.Fiber Scheduling
Scheduling
한 스레드안에 파이버들은 파이버 관리자에 의해 조정됩니다.
파이버들은 선제적으로(preemptively) 제어하기보다는 협력적으로(cooperatively) 제어합니다.
현재 실행 중인 파이버는 제어권을 관리자에게 전달하는 일부 작업을 호출할 때까지 제어권을 유지합니다.
파이버가 일지중지(suspends)(또는 양보(yields))될 때마다 파이버 관리자는 스케줄러를 참조하여
다음에 실행될 파이버을 결정합니다.
Boost.Fiber는 파이버 관리자를 제공하지만 스케줄러는 사용자 정의(선택) 지점입니다.
(사용자 정의(Customization)를 참조하세요.)
각 스레드에는 자체 스케줄러가 있습니다. 프로세스의 다른 스레드는 다른 스케줄러를 사용할 수 있습니다.
기본적으로 Boost.Fiber는 각 스레드의 스케줄러로 'round_robin'을 암시적으로 인스턴스화합니다.
자신의 알고리즘 하위 클래스를 코딩하는 것이 명시적으로 허용됩니다.
대부분의 경우 알고리즘 하위 클래스는 크로스 스레드(cross-thread) 호출을 방어할 필요가 없습니다.
파이버 관리자는 이러한 호출을 가로채서 연기합니다.
대부분의 알고리즘 메서드는 아래에 설명된 예외를 제외하고 관리 중인 파이버가 있는 스레드에서만 직접 호출됩니다.
use_scheduling_algorithm()을 호출하여 알고리즘 하위 클래스가 특정 스레드에 참여합니다.
스케줄러 클래스는 인터페이스 알고리즘을 구현해야 합니다.
Boost.Fiber는 'round_robin', 'work_stealing', 'numa::work_stealing' 및 'shared_work'와 같은 스케줄러를 제공합니다.
이 예제에서는 std::thread::hardware_concurrency()가 반환하는 만큼의 스레드를 생성합니다.
각 스레드는 work_stealing 스케줄러를 실행합니다.
이 스케줄러의 각 인스턴스는 프로그램에서 작업 도용(work-stealing) 스케줄러를 실행하는 스레드 수를 알아야 합니다.
한 스레드의 로컬 큐에 준비된 파이버가 부족하면 스레드는 이 스케줄러를 실행하는 다른 스레드에서 준비된 파이버를 훔치려고 합니다.
📦 Class algorithm
알고리즘은 파이버 스케줄러가 구현해야 하는 인터페이스를 정의하는 추상 기본 클래스(abstract base class)입니다.
algorithm: round_robin, work_stealing, shared_work
🔧 Member function awakened()
- Effects: 파이버 f가 실행될 준비가 되었음을 스케줄러에 알립니다. Fiber f가 새로 실행되었을 수도 있고, 차단되었지만 방금 깨어났을 수도 있고, this_fiber::yield()를 호출했을 수도 있습니다.
- Note: 이 방법은 스케줄러가 실행할 준비가 된 파이버 컬렉션에 파이버 f를 추가하도록 조언합니다. 일반적인 스케줄러 구현은 f를 대기열에 배치합니다.
- See also: round_robin
🔧 Member function pick_next()
- Returns: 다음에 재개될 파이버, 또는 준비된 파이버가 없으면 nullptr입니다.
- Note: 스케줄러가 실제로 다음에 실행할 파이버를 지정하는 곳입니다. 일반적인 스케줄러 구현은 준비 대기열의 선두를 선택합니다.
- See also: round_robin
🔧 Member function has_ready_fibers()
- Returns: 스케줄러에 실행할 준비가 된 파이버가 있으면 true입니다.
🔧 Member function suspend_until()
- Effects: abs_time 시점까지 파이버가 준비되지 않음을 스케줄러에 알립니다.
- Note 1:
이 방법을 사용하면 사용자 정의 스케줄러가 어떤 방식으로든 포함 환경에 대한 제어권을 양보할 수 있습니다.
파이버 관리자는 abs_time 또는 algorithm::notify()가 호출될 때까지 suspend_until()이 반환될 필요가 없다고 명시하고 있습니다.
notify()과의 상호작용은 예를 들어 std::this_thread::sleep_until(abs_time)을 호출하는 것이 너무 단순하다는 것을 의미합니다. round_robin::suspend_until()은 'std::condition_variable'을 사용하여 round_robin::notify()와 조화를 이룹니다. - Note 2: notify()이 다른 스레드에서 호출될 수 있다는 점을 고려하면 (나머지 알고리즘 구현과 마찬가지로) suspend_until() 구현은 notify() 구현과 공유하는 모든 데이터를 보호해야 합니다.
🔧 Member function notify()
- Effects: algorithm::suspend_until()에 대한 보류 중인 호출에서 복귀하도록 스케줄러를 요청합니다.
- Note: 알고리즘 메서드 중 유일하게 다른 스레드에서 notify()을 호출할 수 있습니다. notify() 구현은 나머지 알고리즘 구현과 공유하는 모든 데이터를 보호해야 합니다.
📦 Class round_robin
이 클래스는 라운드 로빈 방식으로 파이버를 예약하는 알고리즘을 구현합니다.
🔧 Member function awakened()
🔧 Member function pick_next()
🔧 Member function has_ready_fibers()
🔧 Member function suspend_until()
🔧 Member function notify()
⚛ 원문