[Linux] Thread-safe vs Reentrant 정리

mommers·2026년 2월 5일

Linux

목록 보기
49/59

Thread-safe vs Reentrant 정리

  • Thread-safe : 여러 쓰레드가 동시에 호출해도 안전함 (주로 Lock/Mutex 사용)
  • Reentrant : 실행 도중 중단되었다가 다시 호출되어도 안전함 (공유 상태 사용 금지)
  • 일반적으로 Reentrant 함수는 Thread-safe하다. 그러나 Thread-safe 함수가 반드시 Reentrant인 것은 아니다.

2. Thread-safe

여러 스레드가 동시에 실행해도 데이터 레이스가 발생하지 않도록 보호된 함수.

예시:

int g_cnt = 0;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

void thread_safe_func() {
    pthread_mutex_lock(&lock);
    g_cnt++;
    pthread_mutex_unlock(&lock);
}

특징:

  • 공유 자원 접근 시 Lock 사용 가능
  • 동시 실행은 안전
  • 인터럽트 중 재진입 시 Deadlock 가능

3. Reentrant

함수가 실행 도중 인터럽트되거나 시그널 핸들러에서 다시 호출되어도 안전한 함수.

조건:

  • 전역 변수 사용 금지
  • static 변수 사용 금지
  • Lock 사용 금지
  • 모든 상태는 호출자가 제공

예시:

void reentrant_func(int *counter) {
    (*counter)++;
}

특징:

  • 오직 인자와 지역 변수만 사용
  • 중단 후 재진입 가능
  • 인터럽트 환경에서도 안전

4. 대표적인 예시: strtok vs strtok_r


4-1) strtok (Non-reentrant, Not Thread-safe)

  • 내부 static 변수를 사용
  • 여러 스레드에서 동시에 사용하면 충돌 발생

4-2) strtok_r (Reentrant)

  • 상태 저장용 포인터를 호출자가 직접 관리
  • 스택 기반 상태 관리
  • Thread-safe 및 Reentrant

5. Async-Signal-Safe 개념

시그널 핸들러 내부에서 호출 가능한 함수 집합.

중요:

  • printf, malloc, free 등은 대부분 Async-Signal-Safe가 아님
  • signal handler 안에서 호출하면 Undefined Behavior 가능
  • POSIX에서 안전하다고 명시한 함수만 사용해야 함 (예: write, _exit 등)

결론

1. Thread-safe: "동시에 여러 명이 써도 되는가?"

→ YES (Mutex 써서 줄 세워도 됨).

2. Reentrant: "쓰다가 중간에 멈추고, 다시 처음부터 실행해도 되는가?"

→ YES (Mutex 쓰면 안 됨, 오직 Stack만 사용).

3. 임베디드/시스템 개발자라면

  • 인터럽트 핸들러나 시그널 핸들러 내부에서는 반드시 Reentrant 함수(Async-Signal-Safe)만 호출해야 한다.
  • printf, malloc 등은 대부분 Non-reentrant이므로 사용하면 안 된다.
  • 멀티스레드 환경에서는 Thread-safe만으로 충분할 수 있지만, 인터럽트/시그널 환경에서는 Reentrant + Async-Signal-Safe가 필수이다.
profile
임베디드 개발자가 되기 위해 공부중입니다!

2개의 댓글

comment-user-thumbnail
2026년 2월 24일

Lock, Mutex 그리고 Semaphore의 차이가 무엇이고 언제 써야 하는건가요?

1개의 답글