QNX RTOS: 4-6. Threads - Operations
2025. 11. 26. 17:31ㆍ운영체제/QNX
스레드를 생성(pthread_create)한 이후, 런타임에 수행할 수 있는 다양한 조작법과 종료 전략을 정리함.
1. 스레드 종료와 뒷정리 (Termination & Join)
1.1. 종료 방법
스레드가 스스로 생을 마감하는 방법은 두 가지임.
- pthread_exit(value) 호출: 즉시 종료하며 value를 남김.
- 함수 리턴: 스레드 메인 함수에서 return value를 함. (내부적으로 pthread_exit이 호출됨)
1.2. pthread_join(): 기다림의 미학
- 역할: 특정 스레드가 종료될 때까지 블로킹(Block)하며 기다림. 종료 시 남긴 반환값(void*)을 받아옴.
- 관계: 프로세스(waitpid)와 달리 부모-자식 관계가 없음. 프로세스 내의 어떤 스레드든 다른 스레드를 Join 할 수 있음.
- 주의: 이미 Join 된 스레드를 또 Join 하면 에러 발생. (Join은 한 번만 가능)
1.3. pthread_detach(): 쿨하게 보내주기
- 기본 동작: 스레드는 종료되어도 누군가 join 해주기 전까지는 종료 상태 정보(좀비와 유사)를 유지하며 자원을 일부 점유함.
- Detach: "난 얘 반환값 필요 없고, 죽으면 알아서 사라지게 해줘"라고 설정하는 것.
- 특징: OS가 종료 즉시 모든 자원을 자동 회수함. 절대 좀비가 되지 않음. 단, join이 불가능해짐.
2. 스레드 식별과 제어 (Identification & Control)
2.1. 식별 (Identity)
- pthread_self(): 자기 자신의 Thread ID를 반환함.
- QNX 특화 기능: QNX API에서는 Thread ID 자리에 0을 넣으면 "나 자신(Calling Thread)"을 의미함. (ID가 1부터 시작하므로 충돌 없음)
2.2. 이름 짓기 (pthread_setname_np())
- 임베디드 디버깅의 핵심임. pidin이나 디버거에서 봤을 때 "Thread 1, 2, 3"으로 뜨면 뭐가 뭔지 모름.
- 이 함수로 "CAN_Rx", "Logger" 같이 이름을 붙여주면 시스템 분석이 매우 쉬워짐.
2.3. 스케줄링 변경 (pthread_setschedparam())
- 실행 중에 스레드의 우선순위나 정책(FIFO, RR)을 바꿀 수 있음.
- 예: 평소엔 낮은 우선순위로 돌다가, 긴급 이벤트 발생 시 스스로 우선순위를 높여서 처리하는 식의 구현이 가능함.
3. 스레드 종료 전략 (Termination Strategy)
RTOS에서 가장 중요한 파트임. 스레드를 외부에서 강제로 죽이는 건 매우 위험함.
3.1. pthread_kill()의 오해
- 이름이 kill이라서 스레드를 죽이는 함수 같지만, 실제로는 "시그널을 보내는 함수"임.
- 시그널을 보냈는데 해당 스레드가 무시(Ignore)하거나 블록(Block)하고 있으면 아무 일도 안 일어남.
- 만약 처리되지 않은 시그널이 발생하면? 프로세스 전체가 죽어버림. (주의 요망)
3.2. pthread_cancel(): 비동기 종료
- POSIX 표준 방식이지만, 비동기적(Asynchronous)이라 위험함.
- 스레드가 리소스(뮤텍스 잠금, 메모리 할당)를 잡고 있는 도중에 캔슬당하면, 자원 해제가 안 된 상태로 죽어버림 -> Deadlock이나 Memory Leak 원인.
3.3. Best Practice: 동기적 자진 종료 (Synchronous Termination)
가장 권장되는 방식은 스레드가 스스로 "죽어야 할 때"를 인지하고 정리 후 죽는 것임.
- Flag Check Loop: 스레드 메인 루프에 while(!done) 같은 조건을 둠.
- Notification: 종료시키고 싶은 쪽에서 done = 1로 만들고 시그널/이벤트로 깨움.
- Cleanup & Exit: 스레드가 루프를 탈출하면서 mutex_unlock, free, close 등을 깔끔하게 수행하고 리턴함.
4. 자원 정리 (Cleanup)
스레드가 종료될 때 정리해야 할 것들:
- 동기화 객체: 잠가둔 뮤텍스(Mutex), RWLock 등 해제.
- 메모리: malloc 한 힙 메모리 해제.
- 핸들: 오픈한 파일, 소켓, 메시지 큐 닫기.
- 스택(Stack): 스레드 스택은 OS가 자동으로 회수함. (단, Main 스레드의 스택은 프로세스 종료 전까지 유지됨)

💡 요약 및 인사이트
- 강제 종료 금지: pthread_cancel이나 외부 킬은 자원 누수(Leak)와 데드락의 지름길임. 무조건 플래그를 보고 스스로 죽게 설계해야 함.
- 이름 붙이기: pthread_setname_np()는 선택이 아니라 필수라고 생각. 나중에 pidin 쳤을 때 스레드 10개가 이름 없이 떠 있으면 분석 불가능함.
- Detach 활용: 반환값이 필요 없는 "Fire-and-Forget" 작업(예: 로그 저장, 단순 이벤트 처리)은 pthread_detach를 써서 리소스를 바로바로 반납하게 하는 게 좋음.
'운영체제 > QNX' 카테고리의 다른 글
| QNX RTOS: 4-8. Synchronization (Race Condition) (0) | 2025.11.26 |
|---|---|
| QNX RTOS: 4-7. Process Termination and Cleanup (0) | 2025.11.26 |
| QNX RTOS: 4-5. Threads - Creation (0) | 2025.11.26 |
| QNX RTOS: 4-4. Thread (0) | 2025.11.26 |
| QNX RTOS: 4-3. Processes - Detecting Termination (0) | 2025.11.26 |