C에서 Mutex Lock 사용

Jinku Hu 2023년10월12일
C에서 Mutex Lock 사용

이 기사에서는 C에서 뮤텍스 잠금을 사용하는 방법에 대한 몇 가지 방법을 설명합니다.

pthread_mutex_t유형 및pthread_mutex_lock함수를 사용하여 코드의 중요 섹션 보호

스레드는 주소 공간을 공유합니다. 이는 전역 변수와 같은 공유 데이터에 대한 수정이 동기화되어야 함을 의미합니다. 그렇지 않으면 잘못된 프로그램 동작이 발생합니다. 다음 코드는pthread_create호출로 4 개의 추가 스레드를 생성하고 실행 시작점으로func3를 전달합니다. func3는 전역 변수shared를 10000 반복for루프에서 하나씩 수정합니다. 따라서 4 개의 스레드가shared값을 각각 10000 씩 증가시키면 프로그램은 40000을 출력해야합니다.

다음 코드를 실행하면 결과는 임의의 정수이지만 40000은 아닙니다.이 동작은 일반적으로 경쟁 조건으로 분류되며, 이는 주어진 스레드가 서로를 참조하지 않고 공유 변수에 액세스 함을 의미합니다. 즉, 종종루프의 실행이 인터리브 될 때 공유 변수의 액세스 및 저장에서 불일치에 도달하고 마지막으로 잘못된 합계가 생성됩니다.

여러 스레드가 메모리에서 동일한 개체를 수정하는 코드 섹션을 중요 섹션이라고합니다. 일반적으로 중요 섹션은 현재 스레드가 실행을 완료하고 모두 올바른 증가 값을 얻을 때까지 다른 스레드가 대기하도록 강제하는 잠금 유형으로 보호되어야합니다. Mutex는func3for루프와 같은 중요한 섹션을 보호하는 데 사용할 수있는 잠금 유형 중 하나입니다.

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

#ifndef NUM_THREADS
#define NUM_THREADS 4
#endif

int shared = 0;

void* func3(void* param) {
  printf("Incrementing the shared variable...\n");
  for (int i = 0; i < 10000; ++i) {
    shared += 1;
  }
  return 0;
}

int main() {
  pthread_t threads[NUM_THREADS];

  for (int i = 0; i < NUM_THREADS; ++i) {
    pthread_create(&threads[i], NULL, func3, NULL);
  }

  for (int i = 0; i < NUM_THREADS; ++i) {
    pthread_join(threads[i], NULL);
  }

  printf("%d\n", shared);
  exit(EXIT_SUCCESS);
}

출력:

Incrementing the shared variable...
Incrementing the shared variable...
Incrementing the shared variable...
Incrementing the shared variable...
30384

이 경우 POSIX 스레드 라이브러리와 내장pthread_mutex_t유형을 사용합니다. pthread_mutex_t유형 변수는 일반적으로정적저장 기간으로 선언됩니다. Mutex는 사용하기 전에 한 번만 초기화해야합니다. 뮤텍스가static으로 선언되면PTHREAD_MUTEX_INITIALIZER매크로를 사용하여 초기화해야합니다. 뮤텍스가 초기화되면 스레드는 이에 따라pthread_mutex_lockpthread_mutex_unlock함수를 사용할 수 있습니다. pthread_mutex_lock은 유일한 인수로 전달 된 뮤텍스 개체를 잠급니다. 뮤텍스가 이미 잠겨 있으면 뮤텍스를 사용할 수있을 때까지 호출 스레드가 차단됩니다. 뮤텍스를 잠금 해제하려면pthread_mutex_unlock을 호출해야합니다. 동일한 뮤텍스에서 대기중인 스레드가있는 경우 스케줄링 정책은 객체 잠금을 얻는 스레드를 결정합니다. 마지막으로 4 개의 스레드 각각에서pthread_join을 호출하고 정수-shared를 인쇄합니다.이 경우 올바른 값이 저장되어야합니다.

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

#ifndef NUM_THREADS
#define NUM_THREADS 4
#endif

int shared = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* func3(void* param) {
  pthread_mutex_lock(&mutex);
  printf("Incrementing the shared variable...\n");
  for (int i = 0; i < 10000; ++i) {
    shared += 1;
  }
  pthread_mutex_unlock(&mutex);
  return 0;
}

int main() {
  pthread_t threads[NUM_THREADS];

  for (int i = 0; i < NUM_THREADS; ++i) {
    pthread_create(&threads[i], NULL, func3, NULL);
  }

  for (int i = 0; i < NUM_THREADS; ++i) {
    pthread_join(threads[i], NULL);
  }

  printf("%d\n", shared);
  exit(EXIT_SUCCESS);
}

출력:

Incrementing the shared variable...
Incrementing the shared variable...
Incrementing the shared variable...
Incrementing the shared variable...
40000
작가: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook