27.3 이그제큐터 이벤트 루프 메커니즘과 비동기 콜백 체인

ROS2 프레임워크에서 노드(Node) 객체 자체는 데이터를 송수신할 수 있는 논리적 엔티티와 콜백(Callback) 함수를 정의할 뿐, 그 스스로 CPU 스레드를 점유하여 실행 루프(Execution Loop)를 구동하지 않는다. 애플리케이션에 정의된 다양한 콜백들이 운영체제 위에서 스케줄링되고 시스템 자원을 할당받도록 매개하는 핵심 컨테이너가 바로 이그제큐터(Executor)이다. 이그제큐터는 블로킹(Blocking) 없는 비동기 통신 모델을 실현하기 위해 내부적으로 정교하게 설계된 이벤트 루프(Event Loop) 메커니즘과 대기 집합(WaitSet) 폴링(Polling) 아키텍처를 운용한다.

0.1 대기 집합(WaitSet) 기반의 이벤트 감지 아키텍처

이그제큐터의 이벤트 루프는 본질적으로 운영체제 커널의 epoll 또는 select 시스템 콜과 유사한 RMW(ROS Middleware) 계층의 대기 집합(WaitSet) 시스템에 크게 의존한다. 이그제큐터에 추가(Add)된 노드 내의 모든 서브스크립션(Subscription), 서비스 서버(Service Server), 타이머(Timer) 및 가드 컨디션(Guard Condition) 등의 감지 대상 객체들은 하나의 전역 rcl_wait_set_t 구조체 포인터 트리에 집결된다.
이그제큐터의 spin() 인터페이스가 호출되면 제어권은 무한 루프 블록으로 진입하며, 루프의 첫 단계에서 RCL(ROS Client Library) 계층의 인터페이스인 rcl_wait() 함수를 호출하여 스레드를 대기 상태(Sleep)로 전환한다. 하위 네트워크 인터페이스 카드(NIC)를 통해 미들웨어 계층(예: DDS)에 새로운 데이터 패킷이 도달하거나, 커널 클록에 의해 타이머의 만료 조건이 충족될 경우 알림 이벤트(Notification Event)가 트리거되어 스레드가 깨어나게 된다. 이 아키텍처는 데이터가 존재하지 않는 유휴 상태의 CPU 사이클 낭비를 극도로 줄여주는 이벤트 주도형(Event-driven) 프로그래밍의 정수이다.

0.2 비동기 콜백 디스패칭(Dispatching) 및 실행 체인

rcl_wait() 함수가 블로킹을 해제하고 반환되면 이벤트 루프는 두 번째 국면인 준비된 엔티티 검사(Ready Entity Inspection) 단계로 전이한다. 이그제큐터는 대기 집합에 등록되었던 엔티티들 중 어느 것이 실제로 이벤트를 발생시켰는지 순회하며 확인한다.
조건이 충족된 엔티티(예: 메시지가 도착한 서브스크립션)가 발견되면, 이그제큐터는 즉시 노드에 등록된 해당 비동기 콜백 함수를 호출 대기열(Ready Queue)로 추출한 후 즉시 디스패치(Dispatch)하여 실행한다. 만약 단일 스레드 이그제큐터(Single-threaded Executor) 시스템이라면 큐에 담긴 콜백들은 순차적으로 한 번에 하나씩만 실행된다. 반면, 다중 스레드 이그제큐터(Multi-threaded Executor) 환경일 경우 스레드 풀(Thread Pool) 내부의 유휴 스레드들에 콜백 작업이 분배되어 물리적 다중 코어 레벨에서의 진정한 병렬 처리(Parallel Processing)가 이루어진다. 이 과정에서 개발자는 콜백 내부에 과도한 블로킹 함수(예: 무한 루프, 긴 sleep)를 삽입하는 것을 철저히 배제해야 이벤트 루프 체인이 정체(Starvation) 상태에 빠지지 않는다.

0.3 콜백 그룹(Callback Group)과 상호 배제 제어

다량의 비동기 센서 데이터를 고주파로 수집하여 처리하는 자율 드론 시스템에서는 스레드 간의 경쟁 조건(Race Condition)을 제어하는 세밀한 정책 메커니즘이 필수적이다. ROS2 이그제큐터는 동시성 문제를 애플리케이션 레벨에서 설정할 수 있도록 콜백 그룹(Callback Group) 추상화를 제공한다.
콜백 그룹은 크게 상호 배제형(Mutually Exclusive)과 재진입 가능형(Re-entrant)으로 분류된다. 기본적으로 모든 노드의 콜백 엔티티들은 디폴트 상호 배제형 콜백 그룹에 소속되어, 다중 스레드 이그제큐터 환경이라 할지라도 완전히 동일한 노드 내의 서로 다른 콜백들이 동시에 병렬 실행되어 내부 상태 변수(State Variable)를 오염시키는 현상을 방어한다. 반면 프로세싱 단가를 낮추기 위해 의도적으로 병렬 연산을 허용해야 하는 독립적인 연산 루틴(예: 다채널 카메라 이미지 필터링)의 경우, 명시적으로 재진입 가능 콜백 그룹 속성을 부여하여 스레드 풀 자원을 최대로 활용할 수 있다. 이처럼 이그제큐터와 콜백 시스템의 융합 아키텍처는 고도의 비동기 이벤트 네트워크망 위에서 실행 타이밍의 무결성을 수학적으로 보장한다.