한땀한땀 정성들인 코딩
동기화 기법, 세마포어 본문
세마포어 - 멀티프로그래밍 환경에서 공유자원에 대한 접근을 제한하여 상호배제하는 기법
세마포어는 3개의 함수를 제공한다. 즉
- 세마포어의 생성 : 자원을 사용하기 위해서 알림판을 만드는 거라고 보면 된다.
- 세마포어의 획득 및 되돌려주기 : 알림판을 사용가능/불가능으로 만드는 작업
- 세마포어의 세부값 제어
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
int semop (int semid, struct sembuf *sops, unsigned nsops);
int semctl(int semid, int semnum, int cmd, union semun arg);
세마포어는 커널이 관리한다. semget을 이용해서 커널에 세마포어의 생성 혹은 기존에 만들어진 세마포어의 접근을 요청할 수 있다. semget의 인자는 다음과 같다.
- key : 세마포어에 접근하기 위한 key 값
- nsems : 세마포어 계수로 접근제한하려는 자원의 수
- semflg : 세마포어 동작제어를 위한 옵션
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <stdio.h>
#define MAX_THREAD 2
int count = 0; //공유변수 count
void *myThreadFunc(void *data);
struct sembuf mysem_open = {0, -1, SEM_UNDO};
struct sembuf mysem_close = {0, 1, SEM_UNDO};
union snum
{
int val;
};
static int semid;
int main(int argc, char **argv)
{
int thr_id;
int status;
int i;
union snum s_union;
pthread_t pt[MAX_THREAD];
semid = semget(2345, 1, 0600|IPC_CREAT);
//세마포어 생성, 하나만 접근가능한 세마포어,세마포어
if(semid == -1) //생성에러
{
perror("semget error");
return 1;
}
s_union.val = 1;
if(semctl(semid, 0, SETVAL, s_union) == -1) //세마포어 초기화
//세마포어id, 세마포어 번호, s_union.val으로 세팅, semun
{
return 1;
}
for(i = 0; i < MAX_THREAD; i++)
{
thr_id = pthread_create(&pt[i], NULL, myThreadFunc, (void *)&i);
//쓰레드 아이디,null,실행할 함수,전달 인자
//성공시 리턴 0
if(thr_id < 0) // 쓰레드 에러
{
perror("Thread Create Error");
return 1;
}
sleep(1);
}
for(i = 0; i < MAX_THREAD; i++)
{
pthread_join(pt[i], NULL); //쓰레드가 종료될때 까지 대기한다.
//실행할 쓰레드 아이디, return받을 인자
}
}
void *myThreadFunc(void *data)
{
int thread_num = *(int *)data;
int lnum;
printf("Thread Create %d\n", thread_num);
while(1)
{
semop(semid, &mysem_open, 1);//연산 실행 함수
//대기하고 락
//세마포어 번호가 0이면 해당 자원에 접근가능
//세마포어id
//sembuf구조체 , 세마포어번호, open or close인수
lnum = count;
sleep(1);
lnum = lnum+1;
count = lnum;
printf("[%d] count : %d\n", thread_num, count);
semop(semid, &mysem_close, 1);
//완료하고 락풀고 세마포어 번호 0으로 증가
}
}
*뮤텍스 vs 세마포어
뮤텍스 = 1개의 접근만 가능한 세마포어