Automotive Software

쓰레드 공유 변수 초기화 한번만 하기 (One-time initialization in Threaded Programming) 본문

포직스 (POSIX)/쓰레드 프로그래밍 고급 (Advanced Threaded Program)

쓰레드 공유 변수 초기화 한번만 하기 (One-time initialization in Threaded Programming)

AutoSW 2020. 9. 22. 00:24

접속 클라이언트 수가 다중 쓰레드에 의해 공유되고, 서버의 첫 구동 시 한 번만 초기화되어 현재까지 접속한 클라이언트의 수를 나타내고 싶을 때, 당연히 생성 쓰레드마다 클라이언트 수를 증가시키겠지만, 증가 전 이 접속 클라이언트 수의 초기화 여부를 어떻게 확인할 것인가?

다중 쓰레드 환경에서 간단한? 방법은...

  1. 하나의 초기화 상태 변수를 선언하고
  2. 이 변수를 보호할 뮤텍스를 하나 정적으로 선언한 후
  3. 그 뮤텍스 보호하에 그 상태 변수의 값을 확인한 후 초기화 여부를 결정

하는 방법일 것이다.

하지만, 뮤텍스를 사용하기 위해 이 뮤텍스 넘을 초기화하기 위한 pthread_mutex_init()을 호출해야 하는데, 이 함수 역시 한 번만 호출되어야 하므로, 다시금 상기 절차를 재귀적(recursively)으로 필요하게 된다.

이러한 문제를 한 번에 해결해 줄 수 있는 넘이 바로 One time initialization (굳이 쉽게 번역하자면, 한 번만 초기화하기 ;> )이다. 이는 함수 pthread_once(pthread_once_t *once_control, void (*init_routine)(void)); 와 해당 변수 타입 pthread_once_t으로 구현할 수 있는데, 두 번째 파라미터로 주어지는 init_routine()의 실행 여부를 첫 번째 파라미터를 통해 결정하는 구조이다.

다시 말하면, 동일한 인자를 사용하여 다중 쓰레드가 pthread_once()를 호출하면 init_routine()은 오직 한번(가장 처음)만 호출되도록 함으로써 init_routine() 내에 초기화되는 변수(경우에 따라 함수는) 한 번만 수행되도록 한다.

 간단한 사용 예는 다음과 같다.

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

pthread_once_t InitOnce = PTHREAD_ONCE_INIT; /* PTHREAD_ONCE_INIT 으로 초기화 되어야 한다. */
int ClientCount;

void init_ClientCount( void )
{
  ClientCount = COUNT_INIT_VALUE; /* 사용자 정의 매크로 */
}

void client_Thread1( void )
{
  /* 클라이언트 카운터 증가전 초기화 여부 확인 */
  pthread_once( &InitOnce, init_ClientCount );

  /* 클라이언트 카운터 증가 구현 */
}

void client_Thread2( void )
{
  /* 클라이언트 카운터 증가전 초기화 여부 확인 */
  pthread_once( &InitOnce, init_ClientCount );

  /* 클라이언트 카운터 증가 구현 */
}

구동가능한 예제는 여기에...

 

쓰레드 공유 변수 한번만 초기화 하기 예제

#include #include #include /* user defined macro */ #define COUNT_INIT_VALUE 0x00 #define COUNT_DUMMY_VALUE 0xA0 pthread_once_t InitOnce = PTHREAD_ONCE_INIT; /* it needs to be initialized as PTHREAD..

autosw.tistory.com