티스토리 뷰

개발/Linux

semaphore 사용하기

Jaeyeon Baek 2016.06.01 10:51

multi-thread 환경의 application에서 thread의 동작을 제어하는 

가장 노멀한 방법은 pthread_cond_wait, pthread_cond_signal가 되겠습니다.


이 방법의 단점으로는 signal에 의해 wait가 풀리고 동작하는데 걸리는 시간이 N초라고 가정했을때

다시 signal을 받아야 하는 시간이 N초 보다 길어야 한다는 점입니다.

그렇지 않다면 signal의 유실이 초래되어 원치 않는 결과가 도래 된다는 것입니다.


물론 이러한 상황이 존재하는 프로그래밍은 좋지 않은 방법이기에 그런 상황은

애초에 만들지 않는게 좋겠지만, 늘 예외는 있으니까요.


그렇다면, wait하는 N초 동안 받는 signal을 모두 처리 하기 위한 방법으로는 semaphore가 있습니다.

semaphore 원자적으로 제어 되는 변수로 값이 0이면 블럭되고 0보다 크면 

접근함과 동시에 semaphore의 값을 1 감소 시킵니다. 


그 제어를 담당하는 함수들이 바로 sem_waitsem_post입니다.

sem_wait는 위에 설명을 담당하고, sem_post는 semaphore의 값을 증가 시키는 역할을 합니다.


간단한 예제 코드를 첨부합니다. 예제 코드를 통해 semaphore의 값이 어떻게 변경되는지 확인하도록 합시다.

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>     /* for exit() */
#include <semaphore.h>  /* for sem_xxxx() */

sem_t semp;
int val;

static void *wait_fun(void *arg)
{
    while(1) {
        sem_wait(&semp);
        sem_getvalue(&semp, &val);
        fprintf(stderr, "thread==> count : %d \n", val);
    }
}

int main(void)
{
    pthread_t pthread_tid = 0;

    sem_post(&semp);
    sem_post(&semp);

    sem_getvalue(&semp, &val);
    fprintf(stderr, "main==> count : %d \n", val);
#if 0
    sem_post(&semp);
    sem_post(&semp);
    sem_post(&semp);
#endif

    if (pthread_create(&pthread_tid, NULL, wait_fun, NULL) != 0 ) {
        printf("failed : wait_fun create \n");
        exit(EXIT_FAILURE);
    }

    pthread_join(pthread_tid, NULL);

    exit(EXIT_SUCCESS);
}



추가로 sem_getvalue는 첫번째 인자로 받는 semaphore의 값을 두번째 인자에 기록해줍니다. 

실행 결과는 모두의 예상처럼 아래와 같습니다.

# ./a.out
main==> count : 2
thread==> count : 1
thread==> count : 0

생각보다 간단한 방법이므로 필요시에 적절하게 사용하면 되겠습니다.



'개발 > Linux' 카테고리의 다른 글

DocuWiki 시간 동기화  (0) 2016.12.19
vim 한글 인코딩 문제  (0) 2016.12.12
semaphore 사용하기  (0) 2016.06.01
[vim] plugin : BufExplorer 사용하기  (0) 2016.02.22
포트 정의 바로알기  (0) 2016.02.17
vi 에서 ASCII Control Codes 입력 (^@ ^A ^B ^[ ^] 같은..)  (0) 2016.01.11
댓글
댓글쓰기 폼