28.3 서브스크립션 이벤트 구동형 콜백 통신 역학

ROS2 아키텍처에서 서브스크라이버(Subscriber)는 텔레메트리, 센서 데이터, 제어 명령 등을 비동기화된 네트워크 망에서 수신하기 위한 수동적(Passive) 데이터 엔드포인트(Endpoint)이다. 이러한 수동적 특성은 운영체제의 폴링(Polling) 방식이 야기하는 CPU 자원 낭비를 방지하기 위해 이벤트 구동형(Event-Driven) 콜백 통신 역학(Callback Communication Dynamics)에 전적으로 의존한다.

1. 네트워크 인터럽트 기반 콜백 트러거 파이프라인

이벤트 구동형 통신 역학의 핵심은 기저 데이터 분배 서비스(DDS) 레이어부터 사용자 정의 애플리케이션 레이어까지 이어지는 체계적인 파이프라인(Pipeline)에 있다. 특정 토픽에 대한 서브스크립션 객체가 생성되면, 미들웨어 계층은 비동기 네트워크 소켓(Network Socket)을 개방하고 수신 대기 상태로 전환한다. 네트워크 하드웨어 추상화 계층에 이더넷 프레임(Ethernet Frame) 단위의 메시지가 도달하면 메모리 복사 및 역직렬화(Deserialization) 연산을 거쳐, C++ 또는 Python의 강타입(Strongly Typed) 메시지 객체로 변환된다.

메시지 조립이 완료되면 DDS는 rcl (ROS Client Library) C API 계층으로 인터럽트 성격의 데이터 가용(Data Available) 이벤트를 발생시킨다. rclcpp 또는 rclpy 런타임은 이 이벤트를 포착하여 연관된 서브스크립션 콜백 큐(Callback Queue)에 메시지의 스마트 포인터 속 참조를 삽입함으로써 내부 버퍼 처리 루틴을 완료한다. 이 모든 과정은 메인 애플리케이션 스레드(Main Application Thread)를 차단(Block)하지 않고 백그라운드 수신 스레드(Background Receive Thread)에서 격리되어 수행된다.

2. 강타입 메시지 주입과 로직 캡슐화

애플리케이션 스레드가 활성화되어 콜백 큐에 적재된 이벤트를 처리할 때, 서브스크라이버 생성 시 등록된 콜백 함수(Callback Function)가 최종적으로 호출된다. 이 때 콜백 함수의 매개변수(Parameter)로는 역직렬화된 메시지 객체의 상수형 참조(Constant Reference, e.g., const std::shared_ptr<const MessageT>)가 주입된다. 이러한 포인터 기반 참조 양도는 메모리 복사 오버헤드(Memory Copy Overhead)를 최소화하여 실시간성을 담보하기 위한 필수적 아키텍처이다.

개발자는 이 콜백 함수 내부에 수신된 데이터를 기반으로 하는 상태 업데이트 알고리즘, 물리 모델 예측, 비행 제어 출력 연산 등의 핵심 논리를 캡슐화(Encapsulate)한다. 한편, 콜백 함수 자체는 해당 노드 클래스의 멤버 메서드(Member Method)로 바인딩(Binding)되는 것이 일반적이다. 이는 콜백 블록 내부에서 클래스의 여타 전용 멤버 변수(Member Variable)에 안전하게 접근하여 노드의 전역 상태(State)를 변경할 수 있도록 객체 지향적 무결성(Integrity)을 제공한다.

3. 실행자(Executor)의 스케줄링 메커니즘과 블로킹 위험성

이러한 콜백 함수들을 언제, 어떻게 메인 CPU 코어에 할당하여 실행할 것인가에 대한 정책은 통신 라이브러리와 분리된 실행자(Executor) 모듈이 전담한다. 단일 스레드 실행자(Single-threaded Executor)는 등록된 모든 노드의 콜백 큐를 순차적으로 활성화(Spin)하여 처리 파이프라인을 작동시킨다.

여기서 가장 주의할 학술적 논점은 단일 스레드 구조 하에서 개별 콜백 내부의 연산 시간이 네트워크 통신 역학에 직접적인 영향을 미친다는 점이다. 만약 조향 제어 메시지를 수신하는 특정 콜백 함수 내부에 무한 반복문(Infinite Loop)이나 파일 I/O 대기(e.g., sleep, 역행렬 계산 등)와 같은 차단형(Blocking) 연산이 내포되어 있다면, 해당 실행자에 소속된 모든 다른 서브스크립션과 타이머 이벤트들이 대기열에 적체되는 교착 상태(Deadlock) 유사 현상에 빠지게 된다. 이를 방지하기 위해 로봇 공학 소프트웨어 아키텍처에서는 콜백 함수 내부의 연산을 O(1) 혹은 매우 짧은 O(N) 확정적 시간표(Deterministic Timetable) 내에 완료되도록 제한하고, 연산 집약적 작업(Compute-Intensive Task)은 독립적인 비동기 스레드 풀(Thread Pool)이나 다중 스레드 실행자(Multi-threaded Executor) 시스템으로 위임하는 설계 패턴을 강제한다.