본문 바로가기

C Language

pthread_mutex_init NULL 초기화

pthread_mutex_init(&forks[i], NULL);는 POSIX 스레드(pthread)에서 뮤텍스(mutex)를 초기화하는 함수입니다. 이 호출을 하나씩 분석하고, 내부 동작, 옵션 설정, 사용 예제를 상세히 설명해 보겠습니다.


🔹 1. pthread_mutex_init() 함수 개요

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);

매개변수

  • pthread_mutex_t *mutex → 초기화할 뮤텍스 객체의 주소
  • const pthread_mutexattr_t *attr → 뮤텍스 속성(attribute) 지정 (기본값 사용 시 NULL)

반환 값

  • 성공 시 0 반환
  • 실패 시 오류 코드 반환
    • EINVAL → attr가 올바르지 않은 경우
    • EAGAIN → 시스템 자원이 부족한 경우
    • ENOMEM → 메모리 부족

🔹 2. &forks[i]의 의미

pthread_mutex_t forks[5]; // 뮤텍스 배열 선언 (철학자 5명 기준)
pthread_mutex_init(&forks[i], NULL);
  • forks[i]는 i번째 뮤텍스 객체입니다.
  • &forks[i]는 해당 뮤텍스 객체의 주소를 전달하여 초기화.

📌 즉, forks는 pthread_mutex_t의 배열이며, &forks[i]는 배열의 i번째 요소(뮤텍스)에 대한 참조를 전달합니다.


🔹 3. NULL 속성의 의미

pthread_mutex_init(&forks[i], NULL);
  • 두 번째 인수 NULL은 기본 뮤텍스 속성(PTHREAD_MUTEX_DEFAULT)으로 설정됨.
  • 기본적으로 빠른(mutual exclusion) 뮤텍스가 사용됨.

📌 속성을 직접 설정하고 싶다면 pthread_mutexattr_t 사용

pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); // 재귀적 뮤텍스 설정
pthread_mutex_init(&forks[i], &attr);
pthread_mutexattr_destroy(&attr); // 속성 객체 제거

🔹 4. 동작 과정 (예제 포함)

✅ 예제: 5개의 철학자가 포크를 사용하도록 뮤텍스를 초기화하는 경우

#include <stdio.h>
#include <pthread.h>

#define NUM_FORKS 5

pthread_mutex_t forks[NUM_FORKS]; // 포크(뮤텍스) 배열

int main() {
    // 뮤텍스 초기화
    for (int i = 0; i < NUM_FORKS; i++) {
        if (pthread_mutex_init(&forks[i], NULL) != 0) {
            perror("Mutex init failed");
            return 1;
        }
    }

    printf("All mutexes initialized successfully.\n");

    // 사용이 끝난 후 뮤텍스 제거
    for (int i = 0; i < NUM_FORKS; i++) {
        pthread_mutex_destroy(&forks[i]);
    }

    return 0;
}

실행 흐름

  1. pthread_mutex_t forks[NUM_FORKS]; → 5개의 뮤텍스를 배열로 선언.
  2. pthread_mutex_init(&forks[i], NULL);을 통해 각 뮤텍스를 초기화.
  3. 모든 뮤텍스가 사용된 후 pthread_mutex_destroy(&forks[i]);로 해제.

🔹 5. 메모리 할당 방식

pthread_mutex_t forks[5];은 **정적 할당(Static Allocation)**을 사용합니다.
하지만 동적으로 할당할 수도 있습니다.

동적 할당 예제

pthread_mutex_t *forks = malloc(sizeof(pthread_mutex_t) * NUM_FORKS);
for (int i = 0; i < NUM_FORKS; i++) {
    pthread_mutex_init(&forks[i], NULL);
}

// 뮤텍스 사용 후 해제
for (int i = 0; i < NUM_FORKS; i++) {
    pthread_mutex_destroy(&forks[i]);
}
free(forks);

차이점

  • 배열 선언 시(pthread_mutex_t forks[5];) → 컴파일 시 크기 결정됨.
  • 동적 할당(malloc()) → 런타임에 크기 조정 가능.

🔹 6. 실패 처리 및 디버깅

pthread_mutex_init()은 실패할 수 있으므로 반환 값을 반드시 체크해야 합니다.

if (pthread_mutex_init(&forks[i], NULL) != 0) {
    perror("Mutex initialization failed");
}

디버깅 포인트

  • 뮤텍스를 초기화하기 전에 사용하면 오류 발생
  • pthread_mutex_destroy()를 호출하지 않으면 메모리 누수 가능

🔹 7. pthread_mutex_init()을 여러 번 호출하면?

pthread_mutex_init(&forks[i], NULL);
pthread_mutex_init(&forks[i], NULL); // ⚠ 두 번 초기화 (잘못된 사용)

결과: 정의되지 않은 동작(Undefined Behavior)

  • 같은 뮤텍스를 여러 번 초기화하면 동작이 보장되지 않음.
  • 초기화 전 반드시 pthread_mutex_destroy() 호출해야 함!

🔹 8. 정리

개념 설명

pthread_mutex_init() 뮤텍스를 초기화
&forks[i] forks 배열의 i번째 뮤텍스의 주소
NULL 속성 기본 속성(PTHREAD_MUTEX_DEFAULT) 사용
반환 값 성공 시 0, 실패 시 오류 코드 반환
동적 할당 가능 malloc()을 사용하여 동적 할당 가능
초기화 전 파괴 필요 기존 뮤텍스를 다시 초기화하려면 pthread_mutex_destroy() 필요

🚀 즉, pthread_mutex_init(&forks[i], NULL);은 i번째 뮤텍스를 기본 설정으로 초기화하는 코드!

'C Language' 카테고리의 다른 글

mutex 입금문제  (2) 2025.03.13
eat 함수  (0) 2025.03.13
뮤텍스 포인터 차이  (0) 2025.03.13
mutex 잠금 원리  (0) 2025.03.13
pthread_mutex_lock pthread_mutex_unlock 설명  (0) 2025.03.12