MultiThreadedExecutor와 콜백 그룹
일꾼을 늘리면 콜백이 동시에 돌까?
스레드 여럿
스레드를 여럿 쓰는 실행기
MultiThreadedExecutor는 스레드 여러 개를 두고 콜백을 나눠 부릅니다. 한 콜백이 오래 걸려도 다른 스레드가 다른 콜백을 부를 수 있습니다. 스레드 수를 따로 정하지 않으면 CPU 코어 수만큼 만듭니다.
rclpy.executors에서 가져옵니다. 7편의 SingleThreadedExecutor 자리에 넣어 씁니다.
그런데
실행기만 바꾸면 그대로입니다
콜백을 따로 묶지 않으면 모두 노드의 기본 콜백 그룹에 들어갑니다. 이 그룹은 한 번에 하나만 돌게 하는 그룹이라, 실행기를 바꿔도 7편과 똑같이 차례로 돕니다.
콜백 그룹
동시에 돌아도 되는지 그룹으로 정합니다
콜백 그룹(callback group)은 두 종류입니다. MutuallyExclusiveCallbackGroup은 그룹 안 콜백이 한 번에 하나만 돌게 합니다. ReentrantCallbackGroup은 같은 콜백까지 동시에 여럿 돌 수 있게 합니다.
기본 콜백 그룹은 MutuallyExclusive입니다. 다른 그룹의 콜백끼리는 MultiThreadedExecutor에서 남는 스레드가 있으면 동시에 돕니다.
코드
만들 때 callback_group으로 넣습니다
그룹 객체를 만들어 노드에 들고 있다가, 타이머·서브스크라이버·클라이언트를 만들 때 callback_group=으로 넘깁니다. 그리고 main에서는 MultiThreadedExecutor로 돌립니다.
예시 코드입니다. 그룹 객체는 self에 저장해 두어야 합니다.
막힘 풀기
기다리는 콜백과 답 받는 쪽을 다른 그룹에
7편에서 멈춘 경우를 풀어 봅니다. 타이머와 서비스 클라이언트를 서로 다른 MutuallyExclusive 그룹에 넣고 MultiThreadedExecutor로 돌리면, 타이머 콜백이 기다리는 동안 다른 스레드가 응답 콜백을 부릅니다.
ROS 2 문서 "Using callback groups"의 예입니다. 둘 다 Reentrant 그룹 하나에 넣어도 됩니다.
정리
입문에서는 이것만 기억합니다
대부분의 입문 노드는 rclpy.spin으로 충분합니다. 실행기와 콜백 그룹은 "콜백끼리 서로 막는다"는 증상이 보일 때 꺼내는 도구입니다. 같은 변수를 고치는 콜백끼리 동시에 돌면 값이 꼬일 수 있으니 같은 MutuallyExclusive 그룹에 둡니다.
다음 강