19.7.2.3. 백그라운드 태스크(&) 실행 및 상태 확인 (`px4_uorb_example status`)

19.7.2.3. 백그라운드 태스크(&) 실행 및 상태 확인 (px4_uorb_example status)

19.7.2.2 단원 말미에서 보았듯, 무식한 px4_uorb_example start 타격 한 방으로 콘솔 프롬프트를 먹통(Lock-up)으로 만들어버리는 참사를 방지하기 위해, 우리는 리눅스 POSIX 쉘의 위대한 유산인 ‘백그라운드 데몬화(Daemonization)’ 기법을 SITL NSH 콘솔에 그대로 차용해야만 한다.

1. 앰퍼샌드(&)의 마법: 데몬(Daemon)으로의 승천

내 모듈을 터미널 제어권에서 완전히 분리해 백그라운드 어둠 속의 WorkQueue 스레드로 우아하게 밀어 넣는 방법은 단 한 글자의 특수기호면 충분하다. 명령어 맨 뒤에 앰퍼샌드(&) 기호를 하나 붙여주자.

px4> px4_uorb_example start &

이 명령어가 들어가는 순간, NSH 쉘은 당신의 new SensorSubscriber() 객체를 힙(Heap) 메모리에 임신시키고 WorkQueue에 스케줄링 티켓만 발급해 둔 뒤, “난 할 일 다 했어“라며 즉시 터미널 제어권을 당신의 키보드 커서에 돌려준다. 화면에는 여전히 영롱한 px4> 프롬프트가 깜빡인다.
하지만 보이지 않는 커널의 시연막 뒤편에서는, 우리가 짠 Run() 콜백 함수가 미친 듯이 jMAVSim의 가짜 센서 데이터를 빨아들이며 초당 수백 번씩 요동치고 있다! 당신의 단순 C++ 스크립트가 진정한 OS 코어 백그라운드 데몬(Daemon) 모듈로 승천한 것이다.

2. 실시간 메모리 덤프 타격: status 트러블슈팅

백그라운드로 코드가 도망가버렸다면, 개발자는 대체 내 코드가 살아서 돌고 있는지(Alive), 아니면 NULL 포인터를 씹고 조용히 대형 사고(Core Dump)를 쳤는지 어떻게 알아낼 수 있을까? printfPX4_INFO로 터미널에 텍스트를 무식하게 도배하는 것은 19.3 단원 시절의 하수나 하는 짓이다.

진정한 아키텍트는 데몬 클래스 내부에 자신의 살아있는 생명줄 데이터를 고스란히 담아두고, 오직 내가 터미널에서 ‘상태 보고를 명령할 때만’ 자신의 뱃속 메모리를 열어 보여주는 젠틀한 객체 덤프(Object Dump) 인터페이스를 구현해 둔다.

당신의 데몬 클래스 내부에는 보통 print_status() 또는 custom_command()라는 오버라이딩된 메서드가 존재한다. NSH 콘솔에서 아래와 같이 타격해 보자.

px4> px4_uorb_example status

status 인자가 커널을 타고 들어가 argv[1]로 파싱 되는 순간, 백그라운드 큐에서 잠자던 당신의 객체가 단발성으로 깨어나 자신이 그동안 수집했던 런타임 변수 메타데이터를 터미널 화면에 단 한 뭉치만 예쁘게 뱉어내고 다시 잠수한다.

[px4_uorb_example] Running: YES
[px4_uorb_example] Subscribed Instance ID: 0 (SPI Main)
[px4_uorb_example] Total Events Harvested: 450,219
[px4_uorb_example] Current Z-Accel Var: -9.81 m/s^2

status 출력 텍스트 4줄이야말로, 당신이 공중에 띄우기 전 짰던 Run() 루프 로직이 단 1번의 틱(Tick) 오차나 레이스 컨디션의 병목 없이 완벽하게 수십만 번의 데이터(Events)를 씹어 삼키고 있음을 증명하는 가장 위대하고 투명한 무결성 수학 성적표이다.

이후 모듈을 죽이고 디버깅을 다시 짜고 싶다면, 잔혹하게 px4_uorb_example stop을 날려 메모리 할당을 통째로 파괴(Destructor delete)하고 다시 처음부터 start & 콤보를 수행하면 된다. 이것이 SITL 환경에서 10년 차 PX4 커널 해커들이 하루에도 수백 번씩 구사하는 start & -> status -> stop 디버깅 철혈 라이프사이클의 모든 것이다.