IT_Programming/System Programming

[Linux] 세마포어 핸들링

JJun ™ 2007. 11. 18. 18:38
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <unistd.h>

union semun
{
    int val;
    struct semid_ds *buf;
    unsigned short int *array;
};

int main(int argc, char **argv)
{
    FILE* fp;
    char buf[11];
    char count[11];
    union semun sem_union;
    int  semid;        
    
    // 세마포어 Lock
    struct sembuf mysem_open  = {0, -1, SEM_UNDO};
    // 세마포어 Unlock
    struct sembuf mysem_close = {0, 1, SEM_UNDO};
    int sem_num;

    memset(buf, 0x00, 11);
    memset(count, 0x00, 11);

    if (argc > 1)
        sem_num = 1;
    else
        sem_num = 0;

    // 세마포어 Handle 얻기
    semid = semget((key_t)3333, sem_num, 0666|IPC_CREAT);
    if (semid == -1)
    {
        perror("semget error ");
        exit(0);
    }  

    printf("semget() success\n");

    if( sem_num == 1 )
    {
        // 세마포어 초기화
        sem_union.val = 1;
        if( semctl(semid, 0, SETVAL, sem_union) == -1 )
        {
            perror("semctl() error");
            exit(0);
        }
    }

    // 세마포어 Lock
    // 다른 프로세스가 사용중이면, 여기서 대기하게 된다.
    if(semop(semid, &mysem_open, 1) == -1)
    {
        perror("semop error ");
        exit(0);
    }

    printf("semop() success\n");
    
    if ((fp = fopen("counter.txt", "r+")) == NULL)
    {
        perror("fopen error ");
        exit(0);
    }

    fgets(buf, 11, fp);
    rewind(fp);

    buf[strlen(buf) - 1] = 0x00;
    sprintf(count, "%d", atoi(buf) + 1);
    printf("%s\n", count);
    sleep(10);
    fputs(count,fp);
    fclose(fp);
    
    // 세마포어 Unlock
    semop(semid, &mysem_close, 1);
    return 1;
}

// 생성된 세마포어를 삭제하기 위해서는 아래와 같이
semctl(semid, 0, IPC_RMID, sem_union);