Execution control library (since C++26)
실행 제어 라이브러리는 일반적인 실행 리소스에서 비동기 실행을 관리하기 위한 프레임워크를 제공합니다.
이 라이브러리는 비동기 연산을 위한 어휘 타입을 제공하고, 간단하고 구성 가능한 방식으로 태스크 실행 그래프를 구축할 수 있도록 하는 것을 목표로 합니다.
목차 |
라이브러리 전체 정의
- Sender : 실행을 위해 전송될 비동기 작업에 대한 설명입니다. (아래의) 연산 상태를 생성합니다.
-
- 송신자(senders)는 비동기적으로 자신의 결과를 "수신자(receivers)"라고 불리는 리스너에게 "전송(send)"합니다.
- 송신자(senders)는 제네릭 알고리즘을 사용하여 태스크 그래프(task graphs) 로 구성될 수 있습니다.
- 송신자 팩토리 및 어댑터(sender factories and adaptors) 는 sender 개념을 만족하는 객체에서 일반적인 비동기 패턴을 캡슐화하는 제네릭 알고리즘입니다.
- Receiver : 비동기 작업 결과를 생성하는 sender가 생산한 결과를 소비하거나 "수신"하는 일반화된 콜백입니다.
-
- 수신자는 발신자가 결과를 전파할 수 있는 세 가지 다른 "채널"을 가집니다: 성공, 실패, 취소됨, 각각 "값", "오류", "중단됨"으로 명명됩니다.
- 수신자는 확장 가능한 실행 환경을 제공합니다: 소비자가 비동기 작업을 매개변수화하는 데 사용할 수 있는 키/값 쌍의 집합입니다.
- Operation State : 비동기 작업에 필요한 상태를 포함하는 객체입니다.
-
- 송신자(sender)와 수신자(receiver)는 std::execution::connect 함수에 전달될 때 연결됩니다.
- 송신자와 수신자를 연결한 결과는 연산 상태(operation state)입니다.
-
연산 상태에서 "
start"가 호출되기 전까지는 실행을 위해 작업이 큐에 들어가지 않습니다. - 시작된 후에는 비동기 연산이 완료되기 전에 연산 상태의 수명이 종료될 수 없으며, 그 주소는 안정적이어야 합니다.
- Scheduler : 실행 컨텍스트에 대한 경량 핸들입니다.
-
- 실행 컨텍스트는 스레드 풀이나 GPU 스트림과 같은 비동기 실행의 소스입니다.
- 스케줄러는 실행 컨텍스트가 소유한 실행 스레드에서 해당 리시버를 완료하는 sender의 팩토리입니다.
라이브러리 유틸리티
개념
스케줄러
|
헤더에 정의됨
<execution>
|
|
|
네임스페이스에 정의됨
std::execution
|
|
|
(C++26)
|
타입이 스케줄러임을 명시
(concept) |
발신자
|
헤더 파일에 정의됨
<execution>
|
|
|
네임스페이스에 정의됨
std::execution
|
|
|
(C++26)
|
타입이 sender임을 지정함
(concept) |
|
(C++26)
|
주어진 연관 환경 타입에 대해 비동기 연산을 생성할 수 있는 sender를 지정함
(concept) |
|
(C++26)
|
특정 receiver 타입과 연결될 수 있는 sender를 지정함
(concept) |
수신기
|
헤더 파일에 정의됨
<execution>
|
|
|
네임스페이스에 정의됨
std::execution
|
|
|
(C++26)
|
타입이 receiver임을 명시
(concept) |
|
(C++26)
|
타입이 주어진 completion signatures에 대한 receiver임을 명시
(concept) |
동작 상태
|
헤더 파일에 정의됨
<execution>
|
|
|
네임스페이스에 정의됨
std::execution
|
|
|
(C++26)
|
타입이 연산 상태임을 지정함
(concept) |
유틸리티 컴포넌트
실행 컨텍스트
|
헤더 파일에 정의됨
<execution>
|
|
|
네임스페이스에 정의됨
std::execution
|
|
|
(C++26)
|
스레드 안전한
MPSC
태스크 큐와 수동으로 구동되는 이벤트 루프를 갖는 실행 리소스
(클래스) |
실행 도메인
|
헤더에 정의됨
<execution>
|
|
|
네임스페이스에 정의됨
std::execution
|
|
|
(C++26)
|
sender 태그로부터 변환을 전달하는 기본 실행 도메인 태그 타입
(클래스) |
|
(C++26)
|
주어진 실행 도메인 태그 아래에서 새로운 sender로 변환
(함수 템플릿) |
|
(C++26)
|
주어진 실행 도메인 태그 아래에서 새로운 쿼리 가능 객체로 변환
(함수 템플릿) |
|
(C++26)
|
주어진 sender 소비자 태그와 인자 집합을 사용하여 sender를 소비하고 주어진 실행 도메인 태그 아래에서 결과를 반환
(함수 템플릿) |
진행 보장
|
헤더 파일에 정의됨
<execution>
|
|
|
네임스페이스에 정의됨
std::execution
|
|
|
스케줄러의 연관된 실행 리소스에 의해 생성된 실행 에이전트의
forward progress guarantee
를 지정함
(열거형) |
|
환경
|
헤더에 정의됨
<execution>
|
|
|
네임스페이스에 정의됨
std::execution
|
|
|
(C++26)
|
쿼리 가능한 객체를 쿼리 객체와 값으로부터 생성
(클래스 템플릿) |
|
(C++26)
|
여러 쿼리 가능한 객체들을 하나의 쿼리 가능한 객체로 집계
(클래스 템플릿) |
|
(C++26)
|
주어진 인자에 대한 연관된 쿼리 가능한 객체를 반환
(커스터마이제이션 포인트 객체) |
쿼리
|
헤더에 정의됨
<execution>
|
|
|
(C++26)
|
쿼리 객체가 쿼리 가능 어댑터를 통해 전달되어야 하는지 여부를 묻습니다
(customization point object) |
|
(C++26)
|
쿼리 가능 객체에 대해 연관된 할당자를 요청합니다
(customization point object) |
|
(C++26)
|
쿼리 가능 객체에 대해 연관된 중지 토큰을 요청합니다
(customization point object) |
|
(C++26)
|
쿼리 가능 객체에 대해 연관된 실행 도메인 태그를 요청합니다
(customization point object) |
|
(C++26)
|
쿼리 가능 객체에 대해 연관된 스케줄러를 요청합니다
(customization point object) |
|
전진 진행 위임 목적으로 작업을 위임하는 데 사용할 수 있는 스케줄러를 쿼리 가능 객체에 요청합니다
(customization point object) |
|
|
발신자의 속성에서 완료 태그와 연관된 완료 스케줄러를 얻습니다
(customization point object) |
|
|
스케줄러에 대해
execution::forward_progress_guarantee
를 묻습니다
(customization point object) |
|
완료 시그니처
|
헤더에 정의됨
<execution>
|
|
|
네임스페이스에 정의됨
std::execution
|
|
|
(C++26)
|
완료 시그니처 집합을 인코딩하는 타입
(클래스 템플릿) |
|
sender의 완료 시그니처를 얻음
(커스터마이제이션 포인트 객체) |
|
|
한 완료 시그니처 집합을 다른 집합으로 변환
(앨리어스 템플릿) |
|
|
sender의 완료 시그니처를 변환
(앨리어스 템플릿) |
|
|
(C++26)
|
sender의 태그 타입을 얻음
(앨리어스 템플릿) |
|
(C++26)
|
sender의 값 완료 타입을 얻음
(앨리어스 템플릿) |
|
(C++26)
|
sender의 오류 완료 타입을 얻음
(앨리어스 템플릿) |
|
(C++26)
|
sender가 중지 완료를 지원하는지 여부를 결정
(변수 템플릿) |
코루틴 유틸리티
|
헤더에 정의됨
<execution>
|
|
|
네임스페이스에 정의됨
std::execution
|
|
|
(C++26)
|
특정 코루틴 내에서 표현식을 awaitable 객체로 변환
(커스터마이제이션 포인트 객체) |
|
코루틴 promise 타입의 기본 클래스로 사용될 때, 해당 코루틴 타입 내에서 sender가 awaitable이 되도록 활성화
(클래스 템플릿) |
|
핵심 연산
동작 상태
|
헤더 파일에 정의됨
<execution>
|
|
|
네임스페이스에 정의됨
std::execution
|
|
|
(C++26)
|
sender
와
receiver
를 연결함
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
operation_state
객체와 연관된 비동기 연산을 시작함
(커스터마이제이션 포인트 객체) |
완성 함수
이러한 함수들은 송신자가 수신자에게 작업 완료를 알리기 위해 호출됩니다.
|
헤더에 정의됨
<execution>
|
|
|
네임스페이스에 정의됨
std::execution
|
|
|
(C++26)
|
성공적인 완료를 나타내는 값 완료 함수
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
계산 또는 스케줄링 중 오류가 발생했음을 나타내는 오류 완료 함수
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
작업이 성공 또는 실패를 달성하기 전에 종료되었음을 나타내는 중단 완료 함수
(커스터마이제이션 포인트 객체) |
송신자 알고리즘
|
이 섹션은 불완전합니다
이유: 현재 표준에 대한 작업 진행 중 |
Sender 팩토리
발신자 팩토리는 발신자를 반환하는 함수이며, 그 매개변수들의 타입에 대해
sender
개념이
false
인 경우입니다.
다음은 발신자 팩토리입니다:
|
헤더 파일에 정의됨
<execution>
|
|
|
네임스페이스에 정의됨
std::execution
|
|
|
(C++26)
|
가변 인자 개수의 인수를 받아들이고, 연결되어 시작될 때 수신자의 값 완료 함수에 인수를 전달하여 동기적으로 완료되는 sender를 반환함
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
단일 인수를 받아들이고, 연결되어 시작될 때 수신자의 오류 완료 함수에 인수를 전달하여 동기적으로 완료되는 sender를 반환함
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
수신자의
set_stopped
를 호출하여 즉시 완료되는 sender를 생성함
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
수신자의 연관 환경을 쿼리하는 sender를 생성함
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
주어진 스케줄러에서 실행을 위한 태스크 그래프를 준비함
(커스터마이제이션 포인트 객체) |
파이프 가능한 발신자 어댑터
|
헤더 파일에 정의됨
<execution>
|
|
|
네임스페이스에 정의됨
std::execution
|
|
|
파이프 가능한 sender adaptor closure 객체를 정의하기 위한 헬퍼 베이스 클래스 템플릿
(클래스 템플릿) |
|
발신자 어댑터
센더 어댑터는 적어도 하나 이상의 매개변수 타입이
sender
개념을 만족하는 함수로서, 반환된 센더가 어댑터 함수의 센더 인수들의 부모 센더인 함수입니다.
다음은 발신자 어댑터입니다:
|
헤더에 정의됨
<execution>
|
|
|
정의된 네임스페이스
std::execution
|
|
|
(C++26)
|
제공된 스케줄러의 실행 리소스에서 실행을 시작하도록 제공된 sender를 적응시킵니다
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
제공된 스케줄러의 실행 리소스에서 완료되도록 제공된 sender를 적응시킵니다
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
제공된 sender를 적응시켜 실행을 제공된 scheduler의 실행 자원으로 전환하여 sender 또는 continuation이 실행된 후, 원래 자원으로 실행을 다시 전환합니다
(customization point object) |
|
(C++26)
|
제공된 sender의 완료에 종속된 작업을 제공된 scheduler의 실행 자원에 스케줄링함
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
입력 sender로부터 전송된 값을 인수로 사용하여 제공된 함수를 호출하는 노드로 태스크 그래프를 연결합니다
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
입력 sender에서 오류가 발생한 경우, 입력 sender가 전송한 오류와 함께 제공된 함수를 호출하는 노드로 태스크 그래프를 연결합니다
(customization point object) |
|
(C++26)
|
입력 sender로부터 "stopped" 신호가 전송될 경우, 제공된 함수를 입력 sender의 중지 동작과 함께 호출하는 노드로 태스크 그래프를 연결합니다
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
입력 sender로부터 전송된 값들을 인수로 사용하여 제공된 함수를 호출하는, 입력 sender에 연결된 노드를 나타내는 sender를 반환합니다
(customization point object) |
|
(C++26)
|
입력 sender에 체인된 노드를 나타내는 sender를 반환하며, 입력 sender에서 오류가 발생한 경우 해당 오류와 함께 제공된 함수를 호출합니다
(customization point object) |
|
(C++26)
|
입력 sender에 체인된 노드를 나타내는 sender를 반환하며, "stopped" 신호가 전송되면 입력 sender의 stop token과 함께 제공된 함수를 호출합니다
(customization point object) |
|
제공된 형태 내의 모든 인덱스와 입력 sender로부터 전송된 값들을 사용하여 함수를 호출하는 다중 발송 sender를 생성합니다. sender는 모든 호출이 완료되거나 오류가 발생한 후에 완료됩니다
(커스터마이제이션 포인트 객체) |
|
|
(C++26)
|
제공된 sender가 multi-shot sender인 경우 해당 sender를 반환하고, 그렇지 않으면 제공된 sender가 전송하는 값과 동등한 값을 전송하는 multi-shot sender를 반환합니다
(customization point object) |
|
(C++26)
|
여러 입력 sender를 모든 입력 sender가 완료된 후에 완료되는 sender로 적응시킵니다
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
여러 입력 sender를 각각 여러 완료 시그니처를 가질 수 있도록 적응시켜, 모든 입력 sender가 완료되면 완료되는 sender로 변환합니다
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
입력 sender가 전송하는 모든 가능한 타입 집합들의 튜플 variant를 전송하는 sender를 반환합니다
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
값 채널을
std::
optional
<
std::
decay_t
<
T
>>
로 매핑하고 중지 채널을
std::
nullopt
로 매핑하는 sender를 반환합니다
(커스터마이제이션 포인트 객체) |
|
(C++26)
|
중지 채널을 오류로 매핑하는 sender를 반환합니다
(커스터마이제이션 포인트 객체) |
발신자 컨슈머
발신자 소비자는 하나 이상의 발신자를 매개변수로 취하고 발신자를 반환하지 않는 알고리즘입니다.
|
헤더 파일에 정의됨
<execution>
|
|
|
네임스페이스에 정의됨
std::this_thread
|
|
|
(C++26)
|
지정된 sender가 완료되고 비동기 결과를 반환할 때까지 현재 스레드를 차단
(customization point object) |
|
여러 완료 시그니처를 가질 수 있는 지정된 sender가 완료되고 비동기 결과를 반환할 때까지 현재 스레드를 차단
(customization point object) |
|
예제
이 예제의 버전은 godbolt.org 에서 확인할 수 있으며, 여기서는 stdexec 을 사용합니다. 이는 std::execution 의 실험적 참조 구현체입니다.
#include <cstdio> #include <execution> #include <string> #include <thread> #include <utility> using namespace std::literals; int main() { std::execution::run_loop loop; std::jthread worker([&](std::stop_token st) { std::stop_callback cb{st, [&]{ loop.finish(); }}; loop.run(); }); std::execution::sender auto hello = std::execution::just("hello world"s); std::execution::sender auto print = std::move(hello) | std::execution::then([](std::string msg) { return std::puts(msg.c_str()); }); std::execution::scheduler auto io_thread = loop.get_scheduler(); std::execution::sender auto work = std::execution::on(io_thread, std::move(print)); auto [result] = std::this_thread::sync_wait(std::move(work)).value(); return result; }
출력:
hello world
참고 항목
|
(C++11)
|
함수를 비동기적으로 실행하며(새 스레드에서 실행될 수 있음) 결과를 담을
std::future
를 반환함
(함수 템플릿) |