Race condition
Critical section
Mutex lock
세마포어
뮤텍스와 세마포어의 차이
Readers-writer lock
deadlock
함수 원형.
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr *attr)
기능. 뮤텍스 객체 초기화
헤더.<pthread.h>
매개변수1.phtread_mutex_t *mutex
초기화 시킬 mutex 객체
매개변수2.const pthread_mutex_attr *attr
뮤텍스의 특징
기본값 NULL(fast; 하나의 스레드가 하나의 잠금만을 얻는 일반적인 형태)
recursive(잠금을 얻은 스레드가 다시 잠금을 얻을 수 있다. 이 경우 잠금에 대한 카운트가 증가함), errorchecking(에러 체크용)
리턴값. 성공0
, 실패-1 errno
함수 원형.
int pthread_mutex_lock(pthread_mutex_t *mutex)
기능. critical section에 진입하기 위해 뮤텍스 잠금을 요청한다.
만약 뮤텍스의 최근 상태가 unlocked면 스레드는 잠금을 얻고 critical section에 진입하게 되고 리턴한다.
다른 스레드가 뮤텍스 잠금을 얻은 상태라면 잠금을 얻을 수 있을 때까지 기다린다.
헤더.<pthread.h>
매개변수.pthread_mutex_t *mutex
lock 시킬 뮤텍스 객체
리턴값. 성공0
, 실패-1 errno
함수 원형.
int pthread_mutex_unlock(pthread_mutex_t *mutex)
기능. 뮤텍스 잠금을 되돌려준다.
만약 뮤텍스 특성이 fast라면, 언제나 unlcoked 상태로 되돌려준다.
만약 뮤텍스 특성이 recursive라면, 잠겨있는 뮤텍스의 수를 감소시키고 이 수가 0이 된다면 뮤텍스 잠금을 되돌려준다.
헤더.<pthread.h>
매개변수.pthread_mutex_t *mutex
unlock 시킬 뮤텍스 객체
리턴값. 성공0
, 실패-1 errno
함수 원형.
int pthread_mutex_destroy(pthread_mutex_t *mutex)
기능. 뮤텍스 객체를 삭제하고 자원을 되돌려준다.
헤더.<pthread.h>
매개변수.pthread_mutex_t *mutex
destroy 시킬 뮤텍스 객체
리턴값. 성공0
, 실패-1 errno
lock된 상태에서 뮤텍스를 destroy하며 안됨 (모든 lock이 다 해제가 되었을 때 destroy 해야한다.)
함수 원형.
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *attr)
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
기능. rwlock 초기화
헤더.<pthread.h>
매개변수1.pthread_lock_t *restrict rwlock
rwlock
매개변수2.const pthread_rwlockattr_t *attr
리턴값. 성공0
, 실패-1 errno
함수 원형.
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
기능. rwlock 제거
헤더.<pthread.h>
매개변수.pthread_rwlock_t *rwlock
rwlock
리턴값. 성공0
, 실패-1 errno
함수 원형.
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
기능. wait for a lock on a read or write lock object for reading
헤더.<pthread.h>
매개변수.pthread_rwlock_t *rwlock
rwlock
리턴값. 성공0
, 실패-1 errno
함수 원형.
int pthread_rwlock_rwlock(pthread_rwlock_t *rwlock)
기능. wait for a lock on a read or write lock object for writing
헤더.<pthread.h>
매개변수.pthread_rwlock_t *rwlock
rwlock
리턴값. 성공0
, 실패-1 errno
함수 원형.
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
기능. unlock a read or write object
If one or more threads are waiting to lock the rwlock,pthread_rwlock_unlock()
causes one or more of these threads to return from therdlock()
orwrlock()
call with the read or write lock object obtained.
If there are multiple threads blocked on rwlock for both read locks and write locks, z/OS UNIX will give the read or write lock to the next waiting call whether it is a read or a write request even when there is a writer blocked waiting for the lock. If no threads are waiting for the rwlock, the rwlock unlocks with no current owner.
헤더.<pthread.h>
매개변수.pthread_rwlock_t *rwlock
rwlock
리턴값. 성공0
, 실패-1 errno
함수 원형.
int sem_init(sem_t *sem, int pshared, unsigned int value)
기능. initialize an unnamed semaphore
세마포어 객체를 value값으로 초기화
헤더.<semaphore.h>
매개변수1.sem_t *sem
세마포어 포인터
매개변수2.int pshared
pshared = 0: 현재 프로세스에서 사용(프로세스 안 스레드끼리 공유)
pshared != 0: 여러 프로세스 간에 공유
(현재 리눅스는 세마포어가 여러 프로세스 간에 공유되는 것을 지원하지 않음. 따라서 0을 쓰지 않는 경우 항상 ENOSYS 에러코드를 반환한다.)
매개변수3.unsigned int value
세마포어가 가지는 초기값. 세마포어를 몇으로 초기화할지 의미한다. (화장실 열쇠를 몇 개로 시작할지 의미)
리턴값. 성공0
, 실패-1 errno
sem_t s; sem_init(&s, 0, 1);
함수 원형.
int sem_post(sem_t *sem)
기능. unlock a semaphore
세마포어 값을 1 증가.
이 함수는 절대로 블록되지 않으며, 비동기 시그널 핸들러에서도 안전하게 사용.
헤더.<semaphore.h>
매개변수.sem_t *sem
세마포어 객체
리턴값. 성공0
, 실패-1 errno
함수 원형.
int sem_wait(sem_t *sem)
기능. lock a semaphore
세마포어 값을 1 감소,
세마포어가 0일 경우에는 1 이상이 될 때까지 스레드는 대기 상태에 있는다.
0이 아닐 경우에는 대기 상태에서 빠져나와 세마포어를 또 1 감소시킨다.
헤더.<semaphore.h>
매개변수.sem_t *sem
세마포어 객체
리턴값. 성공0
, 실패-1 errno
함수 원형.
sem_t *sem_open(const char *name, int oflag, /* mode_t mode, unsigned int value */)
기능. 새로운 기명 세마포어를 생성하거나 기준 파일을 열 때 사용한다.
기명 세마포어는sem_init()
으로 생성된 무명 세마포어보다 느리다.
세마포어는 시스템이 살아있기만 하면 계속 존재한다.
헤더.<semaphore.h>
매개변수1.const char *name
생성 또는 접근하고자 하는 세마포어의 이름
매개변수2.int oflag
세마포어 생성 시의 플래그. 이 두 가지 조합으로 사용 가능(O_CREAT/O_EXCL)
매개변수3.mode_t mode
플래그를 O_CREAT로 설정하면 mode 인자를 받을 수 있음. <sys/stat.h>을 include하면 다음 상수들을 활용할 수 있음(S_IRWXR 그룹접근, S_IRWXO 타인접근, S_IRWXU 개인접근)
매개변수4.unsigned int value
세마포어 초기값으로 0보다 큰 정수여야 함.
unlock된 세마포어의 갯수를 의미함. 이 값은 SEM_VALUE_MAX를 초과할 수 없다.
리턴값1. 성공sem_t
세마포어 포인터
리턴값2. 실패SEM_FAILED + errno
에러
함수 원형.
int sem_unlink(const char *name)
기능. 세마포어 제거
헤더.<semaphore.h>
매개변수.const char *name
지우고자 하는 세마포어의 이름
리턴값. 성공0
, 실패-1 errno
함수 원형.
int sem_getvalue(sem_t *sem, int *sval)
기능. 세마포어 현재값 추출
헤더.<semaphore.h>
매개변수1.sem_t *sem
세마포어 객체
매개변수2.int *sval
sval이 가리키는 위치에 세마포어 현재 값을 저장
리턴값. 성공0
, 실패-1 errno
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
void *read(void *data);
void *accumulate(void *data);
static sem_t sem_one;
static sem_t sem_two;
static int num;
int main(int argc, char *argv[])
{
pthread_t p1, p2;
sem_init(&sem_one, 0, 0);
sem_init(&sem_two, 0, 1);
pthread_create(&p1, NULL, read, NULL);
pthread_create(&p2, NULL, accumulate, NULL);
pthread_join(p1, NULL);
pthread_join(p2, NULL);
sem_destroy(&sem_one);
sem_destroy(&sem_two);
return 0;
}
void *read(void *data)
{
int i;
for (i = 0; i < 5; i++) {
fputs("Input num: " ,stdout);
sem_wait(&sem_two);
scanf("%d", &num);
sem_post(&sem_one);
}
return NULL;
}
void *accumulate(void *data)
{
int sum = 0;
int i;
for (i = 0; i < 5; i++) {
sem_wait(&sem_one);
sum += num;
sem_post(&sem_two);
}
printf("Result: %d\n", sum);
return NULL;
}