동기화가 뭔지에 대해선 설명하지 않겠다. 리눅스에서 쓰레드 동기화를 위해 사용하는 mutex 와 semaphore 에 대해서 간략한 사용방법을 설명한다.

1. 뮤텍스(mutex)

리눅스에서 사용하는 mutex는 pthread에서 사용하는 mutex를 사용한다. 이 pthread mutex는 프로세스간 동기화에도 사용할 수는 있으나 리눅스에서는 잘 사용하지 않고 쓰레드간 동기화에 사용한다. 이 mutex 관련 함수는 다음과 같다.

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr );
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);

 

pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr )

mutex 를 생성하고 초기화 한다.

pthread_mutexattr_t : mutex 생성시 속성 값으로 { FAST, RECURSIVE, ERROR CHECKING } 이 있으며 보통 NULL 을 준다.

또한 pthread_mutex_init 함수를 사용하지 않고 상수들을 이용하여 정적으로 초기화 할 수 있다.

pthread_mutex_t   mutex_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t   mutex_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ;
pthread_mutex_t   mutex_lock = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;

 

 

pthread_mutex_lock(pthread_mutex_t *mutex)

lock을 실행한다. 이미 다른곳에서 lock이 된 경우 , unlock 될 때까지 블록킹 된다.

 

pthread_mutex_trylock(pthread_mutex_t *mutex)

lock을 실행한다. 이미 다른곳에서 lock이 된경우, EBUSY를 리턴 한다.

 

 

pthread_mutex_unlock(pthread_mutex_t *mutex)

unlock을 실행한다.

 

pthread_mutex_destroy(pthread_mutex_t *mutex)

mutex를 삭제한다.

 

 

2. 세마포어(semaphore)

mutex와 유사하지만, mutex는 하나의 접근만 허용하지만 semaphore는 여러개의 접근도 허용하게 해준다. 또한 semaphore는 프로세스 , 쓰레드 에서 사용 될 수 있으며, SYSTEM V, POSIX 로 구분 된다.

 

2.1 SYSTEM V

SYSTEM V 는 전통적 semaphore 방식이다.

int semget(key_t key, int nsems, int semflag);
int semctl(int semid, int semnum, int cmd, union semun arg);
int semop(int semid, struct sembuf *sops, size_t nsops);

 

int semget(key_t key, int nseems, int semflag)

semaphore를 생성한다.

key_t : semaphore 식별 ID 로 IPC_PRIVATE (0 ) 또는 임의의 수, ftok() 함수에서 리턴하는 값으로 사용할수 있다.

nseems : semaphore 집합 갯수

semflag : IPC_CREATE 일 경우 key id 가 없으면 생성하도록 한다. IPC_EXCL 일 경우 key id가 존재 시 실패를 리턴한다.(이 경우 기존 미리 생성된 semaphore를 사용못한다)

 

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

semaphore를 제어한다.

semid: semaphore 식별 ID

semnum : semaphore 집합내의 위치

cmd : 제어 명령

GETVAL : semaphore 값을 구한다.
GETPID : semaphore에 가장 최근에 접근했던 프로세서 ID 구한다.
GETNCNT : semaphore값이 증가하기를 기다리는 프로세스의 갯수
GETZCNT : semaphore값이 0이 되기를 기다리는 프로세스의 갯수
GETALL : semaphore 집합의 모든 semaphore 값을 구한다.
SETVAL : semaphore 값을 설정한다.
SETALL : semaphore 집합의 모든 semaphore 값을 설정
IPC_STAT : 정보를 구한다.
IPC_SET : semaphore 소유권과 접근허가를 설정한다.
IPC_RMID : semaphore 집합을 삭제한다.

arg: semaphore의 값을 설정하거라 값을 얻을 때 사용하는 변수

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

 

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

semaphore값을 변경하는 함수이다.

semid: semaphore 식별 ID

sops : semaphore 설정값 변경을 위한 값

struct sembuf {
    short sem_num;   semaphore  집합 번호
    short sem_op;     semaphore 증감값
    short sem_flg;     옵션(IPC_NOWAIT : 호출 시 실행 못했을 때 실패 리턴. SEM_UNDO : 프로세서 종료시 semaphore 설정을 원래 상태로 복귀 하는 옵션. 보통 이 옵션 사용) 
}

nsops : 변경하려는 갯수

 

2.2 POSIX semaphore

int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_wait(sem_t *sem);
int sem_trywait(sem_t* sem);
int sem_post(sem_t *sem);
int sem_getvalue(sem_t *sem, int *sval);
int sem_destroy(sem_t *sem);

sem_init(sem_t *sem, int pshared, unsigned int value)

semaphore 값을 value로 초기화 한다.

pshared : 0 이면 현 프로세스 에서 사용, 그외에는 여러 프로세스 에서 사용



sem_wait(sem_t *sem)

semaphore 값을 1 줄이고 , 0 일 경우 대기한다.



sem_trywait(sem_t *sem)

sem_wait와 동일한 기능을 하며 0일 경우 EAGAIN을 리턴한다.



sem_post(sem_t *sem)

semaphore 값을 1 증가 시킨다.



sem_getvalue(sem_t *sem, int *sval)

semaphore 값을 sval에 저장한다.



sem_destroy(sem_t *sem )

semaphore 삭제하고 해제한다.

+ Recent posts