Executor와 Callback Group 활용법 연습문제 정답
시행일·최종 수정일: 2026년 9월 1일
정답을 보기 전에
먼저 각 문제에 자신의 말로 답해본 뒤 해설과 비교해 보세요. 표현이 달라도 핵심 개념과 계산 과정이 맞으면 정답으로 볼 수 있습니다.
1. 자신의 Node에서 Subscription·Timer·Service·Action Callback 목록과 Group 배치표를 작성하세요.
정답과 해설
각 Entity, Callback 이름, 실행 주기·최악 실행 시간, 공유 상태, Blocking 여부와 현재 Group을 기록합니다. Control·Sensor·Service·Action의 진행성 요구를 기준으로 Group을 나누고 병렬 실행 가능한 조합을 표시합니다.
2. SingleThreaded BlockingDemo의 fast Timer 간격 max·p95를 측정하세요.
정답과 해설
각 시작 시각 차이를 List에 저장해 정렬한 뒤 max와 95 Percentile을 계산합니다. 0.4초 Slow Callback 구간에서 0.1초 목표보다 간격이 크게 벌어지는지 확인하고 CPU·실행 조건도 함께 기록합니다.
3. Executor만 MultiThreaded로 바꾸었을 때 결과가 같은 이유를 설명하세요.
정답과 해설
Group을 지정하지 않은 두 Timer는 같은 기본 MutuallyExclusive Group에 속합니다. Worker Thread가 여러 개여도 Group이 동시에 하나의 Callback만 허용하므로 실질적으로 직렬 실행됩니다.
4. 두 Timer를 별도 MutuallyExclusive Group으로 분리하고 다시 측정하세요.
정답과 해설
Group 객체 두 개를 Node 멤버로 보관하고 각 Timer의 callback_group에 지정합니다. MultiThreadedExecutor에서 sleep 중 Fast Timer가 실행되는지 비교하되 CPU-bound 작업에서는 Python GIL 영향도 기록합니다.
5. Thread 1·2·4·8개 조건에서 CPU와 최악 지연을 비교하세요.
정답과 해설
입력 부하와 Group 배치를 고정하고 Thread 수만 바꿔 max·p95·p99 간격, 처리량, Process·Thread CPU와 Memory를 측정합니다. 개선이 멈추거나 Context Switch 비용이 커지는 지점을 운영 후보로 삼습니다.
6. sleep 기반 I/O 흉내와 순수 Python CPU 계산의 차이를 비교하세요.
정답과 해설
sleep은 대기 중 GIL을 놓으므로 다른 Worker가 진행하기 쉽습니다. 순수 Python 계산은 GIL 때문에 여러 Thread가 있어도 CPU 병렬 처리 이점이 제한될 수 있어 C++·별도 Process·가속 Library를 검토합니다.
7. 같은 기본 Group의 동기 Service Deadlock을 격리 환경에서 재현하세요.
정답과 해설
Timer와 Client를 기본 MutuallyExclusive Group에 두고 Timer 안에서 동기 Response를 기다립니다. Timer가 Group을 점유해 Future 완료 Callback이 실행되지 못하는 것을 Timeout과 Log로 관찰하며 실물 Command Service에는 적용하지 않습니다.
8. 위 Service Client를 call_async와 Done Callback 구조로 수정하세요.
정답과 해설
future = client.call_async(request) 후 future.add_done_callback(...)으로 결과를 처리합니다. Service Ready, 예외, Timeout, 중복 요청과 종료 시 Future Cancel 정책도 포함합니다.
9. Pose·Timestamp의 Race Condition Test와 Snapshot 해법을 구현하세요.
정답과 해설
Writer가 Pose와 Stamp 사이에 의도적 지연을 넣고 Reader가 불일치 조합을 검출하게 합니다. 두 값을 하나의 Lock 안에서 함께 교체하고 Reader도 같은 Lock에서 지역 Snapshot으로 복사하도록 수정해 반복 Test합니다.
10. Lock 안에서 Publish하는 Code를 찾아 Critical Section을 줄이세요.
정답과 해설
Lock 안에서는 필요한 공유값만 지역 변수로 복사하고 즉시 해제합니다. 계산·Serialization·Log·Publish와 Service 호출은 밖에서 수행하고 변경 전후 Lock 대기 시간과 Callback 최악 지연을 비교합니다.
11. Action Execute 중 Cancel이 100 ms 이내 처리되는지 시험하세요.
정답과 해설
Execute와 Cancel이 진행 가능한 Group·Thread를 구성하고 Goal을 보낸 뒤 여러 시점에 Cancel합니다. Cancel 수신부터 Hardware Stop·Canceled Result까지 시간을 계측하며 Execute Loop의 Cancel 확인 주기는 100 ms 요구보다 짧아야 합니다.
12. Scan Message Age가 250 ms를 넘으면 정지하는 Watchdog를 구현하세요.
정답과 해설
Scan Header Stamp 또는 수신 시각과 현재 Clock의 차이를 계산합니다. 250 ms 초과, Clock 역행, NaN·Inf 또는 미수신이면 Zero Twist를 내고 Fault를 유지하며 새 Data 한 건만으로 성급히 복구하지 않도록 정책을 정합니다.
13. Python과 C++ MultiThreaded 예제의 CPU-bound 결과를 비교하세요.
정답과 해설
동일한 계산량·Rate·Thread·Group 조건에서 처리량, max·p99 지연과 Core 사용률을 측정합니다. Python GIL과 C++ 실제 병렬성의 차이를 기록하되 Algorithm·Compiler·Logging 차이가 섞이지 않게 조건을 고정합니다.
14. Component Container의 Executor Type·Thread 수를 바꾸어 측정하세요.
정답과 해설
지원 배포판에서 Single, Multi와 제공되는 Event 기반 Container를 확인합니다. 같은 Component·입력으로 Thread 수별 지연·CPU·Memory를 비교하고 한 Component의 긴 Callback이 다른 Component에 미치는 영향도 측정합니다.
15. 실제 Robot 적용 전 Failure Injection·E-stop·Rollback Checklist를 작성하세요.
정답과 해설
Sensor 단절·지연, Service Timeout, Action Cancel, CPU 포화와 종료 중 Hang을 주입합니다. Watchdog·E-stop·속도 제한을 검증하고 이전 Executor 설정과 Image로 복귀하는 절차, 관측 Metric과 승인 조건을 준비합니다.
학습 마무리
틀린 문제는 강의의 관련 장을 다시 읽고, 용어뿐 아니라 각 개념이 실제 로봇에서 어떤 역할을 하는지 설명해 보세요.