Automotive Software

pthread_once()를 이용한 쓰레드 공유 변수 한번만 초기화 하기 예제 본문

포직스 (POSIX)/쓰레드 프로그램 예제 (Thread Program Example)

pthread_once()를 이용한 쓰레드 공유 변수 한번만 초기화 하기 예제

AutoSW 2020. 9. 22. 18:46
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

/* 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_ONCE_INIT */
int ClientCount = COUNT_DUMMY_VALUE;

void init_ClientCount( void )
{
  printf("ClientCount(), Before : ClientCount = %d\n", ((COUNT_DUMMY_VALUE == ClientCount)? COUNT_DUMMY_VALUE : ClientCount));
  ClientCount = COUNT_INIT_VALUE; /* user defined macro */
  printf("ClientCount(), After : ClientCount = %d\n", ClientCount);
}

void *client_Thread( void *arg )
{
  /* check and init. once, if it is not initialized */
  (void)pthread_once( &InitOnce, init_ClientCount ); /* return vlaue is ignored, since the once-object is initialized */

  /* increment the counter */
  ClientCount += 1;

  printf("client_Thread(), The number of clients : %d\n", ClientCount);

  return arg;
}

void run_Thread( void )
{
    pthread_t threadId;
    void *threadRet;
    int retVal;

    retVal = pthread_create(&threadId, NULL, client_Thread, NULL);
    if(retVal != 0 )
    {
        printf("run_Thread(), Failed with pthread_create()");
        abort();
    }
    else
    {
        printf("run_Thread(), Thread ID : %ld is created\n", threadId);

        /* further handling is required, e.g., pthread_join() */
    }
}

int main( void )
{
    char inputCh;
    printf("Enter your command (t->Thread, q->quit): ");

    while(1)
    {
        if( scanf("%c", &inputCh) )
        {
            switch(inputCh)
            {
                case 'q':
                {
                    printf("Bye : Exit this program\n");
                    exit(EXIT_SUCCESS);
                    break;
                }
                case 't':
                {
                    printf("Run the Thread\n");
                    run_Thread();
                    break;
                }
                case 0x0a:
                {
                    /* enter */
                    break;
                }
                default : 
                {
                    printf("Try again : ");
                    break;
                }
            }
        }
    }

    return 0;
}
pthread_once_t 타입은 운영체제에 따라 형태의 차이가 있다.
Linux, BSD기반 운영체제에서는 간단히 int 형으로 구현되고,
다른 상용 운영체제에서는 추가적인 멤버를 포함하는 구조체로 구현되기도 한다.

테스트 결과 : 단 한번 ClientCount 변수를 초기화하기 위한 ClientCount()가 호출됨을 확인할 수 있다.

본 예제는 리눅스상에서 테스트하였습니다.

TIP! 아래와 같은 링크 에러가 발생하는 경우, pthread 라이브러리와 사전에 정의된 매크로 등을 모두 사용하기 위해 -lpthread 대신 -pthread 옵션을 사용하는 것을 권장함
initOnce.c:22: undefined reference to `pthread_once'
initOnce.c:38: undefined reference to `pthread_create'

쓰레드상에서 공유 변수 한 번만 초기화 하기 설명은 여기에...

 

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

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

autosw.tistory.com