[리눅스 시스템 프로그래밍_Day5]세마포어, 뮤텍스
■세마포어와 뮤텍스■
*동기화 : 두 개 이상의 프로세스가 동일한 자원에 접근할 때 잘못된 연산을 없애고 일관성을 보장한다.
*세마포어
// sem_test_a.c //
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
sem_t sem; /*TODO: semaphore variable - sem */
pthread_t task;
void Thread( void ) {
int i = 0;
int val;
while(1) {
i++;
sem_wait( &sem ); /* TODO: take semaphore */
sem_getvalue( &sem, &val ); /* get sem value to val */
printf( "wakeup %d: value = %d\n", i ,val );
if ( i > 5 ) break;
}
}
//----------------------------------------
void main( void )
{
int i = 0, j, val;
sem_init( &sem, 0, 3 ); /* TODO: init unnamed semaphore */
pthread_create( &task, NULL, (void*(*)(void*))Thread, NULL );
while(1) {
sleep(1);
i++;
printf( "sem post %d\n", i );
sem_post( &sem ); /* TODO: give semaphore */
sem_getvalue( &sem, &val ); /* get sem value to val */
printf( "sem value = %d\n", val );
if ( i > 5 ) break;
}
}
# cc sem_test_a.c -lpthread
# ./a.out
wakeup 1: value = 2
wakeup 2: value = 1
wakeup 3: value = 0
sem post 1
sem value = 1
wakeup 4: value = 0
sem post 2
sem value = 1
wakeup 5: value = 0
sem post 3
sem value = 1
wakeup 6: value = 0
sem post 4
sem value = 1
sem post 5
sem value = 2
sem post 6
sem value = 3
/*
현재 6번의 테스크가 실행되게 되어있다.
세마포어는 count가 0이되면 스레드는 block이 된다 (사용 불가능) ==> sem_wait( &sem ); 가 block이 된다
wakeup 1: value = 2
wakeup 2: value = 1
wakeup 3: value = 0
부분에서 모두 사용 하였고
sem post 1
sem value = 1
//이때는 반환을 하는 것을 출력하였는데 count가 증가한다 즉, 대기큐에 있는 프로세스들을 깨워 ready 큐로 이동한다. 그래서 count가 증가하여 value도 증가해서 1
wakeup 4: value = 0 //이때 또 task를 실행함으로써 count는 감소
sem post 2
sem value = 1
wakeup 5: value = 0
sem post 3
sem value = 1
wakeup 6: value = 0 //까지 반복한다.
sem post 5
sem value = 2
sem post 6
sem value = 3
//모든 테스크가 끝났을때를 보면 초기값인 value가 3까지 증가한다.
만약 main에서 while의 수가 늘어나면 세마포어는 생성되어진다.
*/
*뮤텍스
잠김, 풀림으로 테스크 동기화 세마포어처럼 동작하나 소유권, 재귀적 접근, 테스크 삭제 보호,
우선 순위 역전 회피 프로토콜 등을 지원한다(생성시 옵션에 의해서 생성)
// mutex_test_a.c //
#include <semaphore.h>
#include <pthread.h>
#include <sys/types.h>
#include <stdio.h>
/* TODO: define mutex variable and initialize */
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int val;
int arg1 = 0, arg2 = 1;
void *Thread( void* arg )
{
int i, j;
for( i = 0; ; i++ ) {
/* TODO: lock the mutex */
pthread_mutex_lock( &mutex );
val = *(int*)arg;
printf( "thread %d: %dth iteration: val = %d\n", *(int*)arg, i, val);
/* TODO: unlock the mutex */
pthread_mutex_unlock( &mutex );
sleep(1);
}
pthread_exit(0);
}
int main( void ) {
pthread_t thread1, thread2;
pthread_attr_t attr;
pthread_attr_init( &attr );
pthread_create( &thread1, &attr, (void*(*)(void*))Thread, &arg1 );
pthread_create( &thread2, &attr, (void*(*)(void*))Thread, &arg2 );
pthread_exit(0);
}
# cc mutex_test_a.c -lpthread
# ./a.out
thread 1: 0th iteration: val = 1
thread 0: 0th iteration: val = 0
thread 1: 1th iteration: val = 1
thread 0: 1th iteration: val = 0
thread 1: 2th iteration: val = 1
thread 0: 2th iteration: val = 0
thread 1: 3th iteration: val = 1
thread 0: 3th iteration: val = 0
thread 1: 4th iteration: val = 1
thread 0: 4th iteration: val = 0
thread 1: 5th iteration: val = 1
thread 0: 5th iteration: val = 0
thread 0: 6th iteration: val = 0
thread 1: 6th iteration: val = 1
// mutex_cond_a.c // Condition variable
#include <stdio.h>
#include <pthread.h>
pthread_t thread;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int count = 0;
void* Thread ( void* arg ) {
pthread_mutex_lock ( &mutex );
while ( count < 5 ) {
printf( "count = %d: wait...\n", count );
/*TODO: wait for condition variable signal */
pthread_cond_wait ( &cond, &mutex );
}
printf( "count = %d: done...\n", count );
pthread_mutex_unlock ( &mutex );
pthread_exit(0);
}
void main ( void ) {
int i;
pthread_create( &thread, NULL, (void*(*)(void*))Thread, NULL );
for ( i = 0; i < 10; i++ ) {
sleep(1);
pthread_mutex_lock ( &mutex );
count++;
/* TODO: signal condition variable 'cond' */
if (1) // check condition
pthread_cond_signal( &cond );
printf( "condition signal %d\n", i );
pthread_mutex_unlock( &mutex );
}
pthread_exit(0);
}
# ./a.out
count = 0: wait...
condition signal 0
count = 1: wait...
condition signal 1
count = 2: wait...
condition signal 2
count = 3: wait...
condition signal 3
count = 4: wait...
condition signal 4
count = 5: done...
condition signal 5
condition signal 6
condition signal 7
condition signal 8
condition signal 9