semget() 세마포어 생성 및 접근
Language/C 2012. 2. 2. 14:00설명
semget() 함수는 세마포어 집합을 생성하거난 이미 생성된 세마포어에 접근하기 위해 사용합니다.
세마포어는 공유 자원을 동시에 여러 프로세스가 사용하는 것을 막고, 오직 자원을 하나의 프로세스만 사용할 수 있도록 보장해 주는 방법입니다. 즉, 여러 프로세스 중 공유 자원을 자신이 사용할 수 있는지 있다면 작업이 끝나기 전까지 다른 프로세스가 공유 자원을 사용할 수 없도록 다른 프로세스의 접근을 제어하는 방법을 세마포어를 이용하여 구현할 수 있습니다.
세마포어를 제일 간단히 설명한다면 특정 변수를 두고, 이 변수를 미리 확인합니다. 특정 변수를 확인하는 함수를 p()라고 하겠습니다.
- 프로세스는 공유자원을 사용하기 전에 p()함수를 호출합니다.
- p()는 특정 변수 값을 확인하여 공유 자원이 다른 프로세스가 사용 중인지의 여부를 판단하고, 다른 프로세스가 사용 중이면 그 프로세스가 사용을 중지할 때까지 대기합니다. 공유 자원이 사용 가능하다면 특정 변수값을 변경하고 복귀합니다.
- 프로세스는 공유 자원을 사용합니다.
- 프로세스는 공유 자원에 대한 작업을 완료했다면 s() 함수를 호출하여 특정 변수값을 원래의 값으로 복원합니다.
이렇게 프로세스가 s() 함수를 호출하여 변수값을 원래 값으로 변경하면 다른 프로세스의 p()함수는 공유 자원의 사용이 가능하다고 판단하게 됩니다.
헤더 | sys/types.h sys/ipc.h sys/sem.h |
|||||||||||||
형태 | int semget ( key_t key, int nsems, int semflg ) | |||||||||||||
인수 |
| |||||||||||||
반환 |
|
예제
아래의 예제에서는 두개의 쓰레드를 만들어 하나의 자원인 카운터 cnt 를 서로 방해하지 않고 사용하는 모습을 보여 주고 있습니다.
#include<pthread.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <sys/ipc.h> #include <sys/sem.h> int cnt = 0; static int semid; void p() { struct sembuf pbuf; pbuf.sem_num = 0; pbuf.sem_op = -1; pbuf.sem_flg = SEM_UNDO; if ( -1 == semop(semid, &pbuf, 1)) printf( "p()-semop() 실행 오류\n"); } void v() { struct sembuf vbuf; vbuf.sem_num = 0; vbuf.sem_op = 1; vbuf.sem_flg = SEM_UNDO; if ( -1 == semop( semid, &vbuf, 1)) printf( "v()-semop() 실행 오류\n"); } void *fun_thread1(void *arg) { while( cnt < 5) { p(); printf( "thread1 실행\n"); cnt++; usleep( 100); printf( "thread1 종료\n"); v(); } return NULL; } void *fun_thread2(void *arg) { while( cnt < 5) { p(); printf( "thread2 실행\n"); printf( "카운터= %d\n", cnt); usleep( 100); printf( "thread2 종료\n"); v(); } return NULL; } 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 ( -1 == (semid = semget( IPC_PRIVATE, 1, IPC_CREAT ¦ 0666))) { printf( "semget() 실행 오류\n"); return -1; } arg.val = 1; // 세마포어 값을 1로 설정 if ( -1 == semctl(semid, 0, SETVAL, arg)) { printf( "semctl()-SETVAL 실행 오류\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 ( -1 == semctl(semid, 0, IPC_RMID, arg)) { printf( "semctl()-IPC_RMID 실행 오류\n"); return -1; } printf( "프로그램 종료\n"); return 0; }
]$ ./a.out a ]$
'Language > C' 카테고리의 다른 글
strerror (0) | 2012.03.14 |
---|---|
bsearch() 함수 설명 및 알고리즘 (0) | 2012.03.09 |
inet_ntoa 64bit 사용시 에러 대처방법 (0) | 2012.02.02 |
FILE, fopen, fprintf, fflush, fclose (0) | 2012.01.30 |
multicast(receive) (0) | 2012.01.16 |