간단하게 리소스 카운터라고 생각해도 되는데 일단은 데드락 피하기 위한

기술 중의 하나라고 한다..

실제 어디다 써먹을지는 아직 모르겠지만.. 이거보다는 개인적으로 뮤텍스를 더 자주 쓰는듯 싶네..

 

소스코드 출처 : http://forum.falinux.com/zbxe/?document_srl=428639

 

int semget ( key_t key, int nsems, int semflg )

세마포어 식별자를 가지고 오는 함수다.

 

key_t key

시스템에서 세머포어를 식별하는 키 번호

int nsems

세마포어 집합 내의 세마포어 개수로 접급 제한하려는 세마포어 자원의 개수

int semflg 동작 옵션 ( IPC_CREATE와 IPC_EXCL이 있다.)

 

 

int semctl ( int semid, int semnum, int cmd, union semun arg)

세마포어를 control 하는 함수다.

 

int semid 시스템에서 세머포어를 식별하는 집합 번호
int semnum

세마포어 집합 내에서의 세마포어 위치 (세마포어 넘버...)

int cmd

제어 명령( 값을 설정, 삭제, 소유권, 등등 많다.)

union semun arg 위의 제어명령 cmd 에 따라 달라진다., 설정 또는 값을 구하는 변수 
union semun{
   int                  val;
   struct   semid_ds   *buf;
   unsigned short int  *arrary;
}

int semop ( int semid, struct sembuf *sops, unsigned nsops )

세마포어의 값을 변경한다. 값을 증가, 감소시킨다.

 

int semid 시스템에서 세머포어를 식별하는 집합 번호
struct sembuf *sops

세마포어 값을 계산하기위한 설정 값 
struct sembuf {
    short sem_num;   세마포어 번호
    short sem_op;     세마포어 증감값
    short sem_flg;     옵션 
}

unsigned nsops

변경하려는 세마포어 개수로 변경하려는 세마포어 개수가 여러 개일 때 사용
n개의 세마포어 옵션들..

 

 

예제를 봐야 이게 뭔지 조금은 이해가 간다.

매우간단한 멀티 쓰레드 구조의 카운터다.

failinux.com.. 참 괜찮다.

 

 

============================================

#include 
#include 
#include 
#include 
#include "sys/ipc.h"
#include "sys/sem.h"
#include "sys/poll.h"

int         cnt   = 0;
static int  semid;

void semop1() 
{
    struct sembuf buf1;

    buf1.sem_num   = 0;
    buf1.sem_op    = -1;
    buf1.sem_flg   = SEM_UNDO;

    if (semop(semid, &buf1, 1) == -1)
        printf( "%s::semop() Fail\n", __func__);
}

void semop2()
{
    struct sembuf buf2;

    buf2.sem_num   = 0;
    buf2.sem_op    = 1;
    buf2.sem_flg   = SEM_UNDO;

    if (semop(semid, &buf2, 1) == -1)
        printf( "%s::semop() Fail\n", __func__);
}

void *fun_thread1(void *arg) {
    while( 1) {
        semop1();
        printf( "thread1 run \n");
        if ( 5 < cnt) {
            printf( "thread1 Completely terminated \n");
            semop2();
            break;
        }
        else {
            cnt++;
            poll(0,0,100);
            printf( "thread1 terminated \n");
        }
        semop2();
    }
    return;
}

void *fun_thread2(void *arg)
{
    while( 1) {
        semop1();
        printf( "thread2 run \n");
        if (5 < cnt) {
            printf( "thread2 Completely terminated \n");
            semop2();
            break;
        }
        else {
            printf( "=====>>Counter= %d\n", cnt);
            poll(0,0,100);
            printf( "thread1 terminated \n");
        }
        semop2();
    }

    return;
}

int main(int argc, char *argv[])
{
    pthread_t thread1;
    pthread_t thread2;
    union semun{
        int                  val;
        struct   semid_ds   *buf;
        unsigned short int  *arrary;
    }arg;

    if ((semid = semget( IPC_PRIVATE, 1, IPC_CREAT| 0666)) == -1) {
        printf( "semget() Fail\n");
        return -1;
    }

    arg.val=1;                // Semaphore value = 1
    if (semctl(semid, 0, SETVAL, arg) == -1) {
        printf( "semctl()-SETVAL Fail\n");
        return -1;
    }

    pthread_create(&thread1, NULL, fun_thread1, NULL);
    pthread_create(&thread2, NULL, fun_thread2, NULL);
    pthread_join( thread1, NULL);
    pthread_join( thread2, NULL);

    if (semctl(semid, 0, IPC_RMID, arg) == -1) {
        printf( "semctl()-IPC_RMID Fail\n");
        return -1;
    }
    printf( "Process Terminated!");
    return 0;
}
/* The end of function */
# 수행결과는 다음과 같다.
./a.out
thread1 run 
thread1 terminated 
thread2 run 
=====>>Counter= 1
thread1 terminated 
thread1 run 
thread1 terminated 
thread2 run 
=====>>Counter= 2
thread1 terminated 
thread1 run 
thread1 terminated 
thread2 run 
=====>>Counter= 3
thread1 terminated 
thread1 run 
thread1 terminated 
thread2 run 
=====>>Counter= 4
thread1 terminated 
thread1 run 
thread1 terminated 
thread2 run 
=====>>Counter= 5
thread1 terminated 
thread1 run 
thread1 terminated 
thread2 run 
thread2 Completely terminated 
thread1 run 
thread1 Completely terminated 

 

 

============================================

 

failinux 그대로 가져왔슴..

개인적인 테스트용이므로,, 저작권에 문제가 있다면

알려주시길.. 지우던지 다른 방식으로 구현해두겠습니다.

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

select 함수 예제  (0) 2012.07.23
Unix Domain Socket 예제  (0) 2012.07.23
semget. semop, semctl 함수 예제  (0) 2012.07.17
mmap / munmap 함수 예제  (0) 2012.07.17
shmget/ shmat 함수 예제  (0) 2012.07.13
C FAQ (포인터 증가 3)  (0) 2012.07.13

+ Recent posts