세마포어를 사용해서 뮤텍스 교착상태 회피하기 (2)

운영체제론 2015. 1. 6. 19:41

#include <stdio.h>

#include <Windows.h>


int print1 = 0;

int print2 = 0;


HANDLE hMutex1; // 뮤텍스1

HANDLE hMutex2; // 뮤텍스2


HANDLE hSemaphore1; // 세마포어1

HANDLE hSemaphore2; // 세마포어2


// 실행될 스레드 1

unsigned int NewThread01(void* pParam)

{

while(1)

{

WaitForSingleObject(hSemaphore1, INFINITE);//세마포어 1번 카운터 감소 카운터가 0이면 무시


WaitForSingleObject(hMutex1, INFINITE); // 뮤텍스1

WaitForSingleObject(hMutex2, INFINITE); // 뮤텍스2


print1++;


ReleaseMutex(hMutex2); // 뮤텍스2 해제

ReleaseMutex(hMutex1); // 뮤텍스1 해제


ReleaseSemaphore(hSemaphore2, 1, NULL); // 세마포어 2번 카운터 증가

}


return 0;

}


// 실행될 스레드 2

unsigned int NewThread02(void* pParam)

{

while(1)

{

WaitForSingleObject(hSemaphore2, INFINITE);//세마포어 2번 카운터 감소 카운터가 0이면 무시


WaitForSingleObject(hMutex2, INFINITE); // 뮤텍스2

WaitForSingleObject(hMutex1, INFINITE); // 뮤텍스1


print2++;

ReleaseMutex(hMutex1); // 뮤텍스1 해제

ReleaseMutex(hMutex2); // 뮤텍스2 해제


ReleaseSemaphore(hSemaphore1, 1, NULL); // 세마포어 1번 카운터 증가

}

return 0;

}


int main(int argc, char* argv[])

{

hMutex1 = CreateMutex(NULL, FALSE, NULL); // 뮤텍스1 초기화

hMutex2 = CreateMutex(NULL, FALSE, NULL); // 뮤텍스2 초기화


hSemaphore1 = CreateSemaphore(NULL, 1, 1, NULL); // 세마포어1 초기화 초기 카운터값1 최대 카운터값1

hSemaphore2 = CreateSemaphore(NULL, 0, 1, NULL); // 세마포어1 초기화 초기 카운터값0 최대 카운터값1;


CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)NewThread01, 0, 0, NULL); // 스레드01 생성

CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)NewThread02, 0, 0, NULL); // 스레드02 생성


while(1)

{

printf("thread 1 : %d\tthread 2 : %d\n", print1, print2);


Sleep(400); // 관찰을 위한 Sleep


}


CloseHandle(hMutex1); // 뮤텍스1 소멸

CloseHandle(hMutex2); // 뮤텍스2 소멸


CloseHandle(hSemaphore1);// 세마포어1 소멸

CloseHandle(hSemaphore2);// 세마포어2 소멸


return 1;

}


역시나 윈도우 버전

:

교착상태 예제 (3)

운영체제론 2015. 1. 6. 19:33

#include <stdio.h>

#include <Windows.h>


int print1 = 0;

int print2 = 0;


HANDLE hMutex1; // 뮤텍스1

HANDLE hMutex2; // 뮤텍스2


// 실행될 스레드 1

unsigned int NewThread01(void* pParam)

{

while(1)

{

WaitForSingleObject(hMutex1, INFINITE); // 뮤텍스1

WaitForSingleObject(hMutex2, INFINITE); // 뮤텍스2


print1++;


ReleaseMutex(hMutex2); // 뮤텍스2 해제

ReleaseMutex(hMutex1); // 뮤텍스1 해제

}


return 0;

}


// 실행될 스레드 2

unsigned int NewThread02(void* pParam)

{

while(1)

{

WaitForSingleObject(hMutex2, INFINITE); // 뮤텍스2

WaitForSingleObject(hMutex1, INFINITE); // 뮤텍스1


print2++;

ReleaseMutex(hMutex1); // 뮤텍스1 해제

ReleaseMutex(hMutex2); // 뮤텍스2 해제

}

return 0;

}


int main(int argc, char* argv[])

{

hMutex1 = CreateMutex(NULL, FALSE, NULL); // 뮤텍스1 초기화

hMutex2 = CreateMutex(NULL, FALSE, NULL); // 뮤텍스2 초기화


CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)NewThread01, 0, 0, NULL); // 스레드01 생성

CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)NewThread02, 0, 0, NULL); // 스레드02 생성


while(1)

{

printf("thread 1 : %d\tthread 2 : %d\n", print1, print2);


Sleep(400); // 관찰을 위한 Sleep


}


CloseHandle(hMutex1); // 뮤텍스1 소멸

CloseHandle(hMutex2); // 뮤텍스2 소멸


return 1;

}


그냥 Windows.h 만 가지고 만들어봄  윈도우용 (하지만 돌아가는건 커맨드창이지롱~)

:

세마포어를 사용해서 뮤텍스 교착상태를 회피하기

운영체제론 2015. 1. 6. 18:02

#include <stdio.h>

#include <pthread.h>

#include <semaphore.h>

#include <Windows.h>


pthread_mutex_t mutex1; // 뮤텍스

pthread_mutex_t mutex2; // 뮤텍스


sem_t sem1; // 세마포어

sem_t sem2; // 세마포어


int intp1 = 0; // 1번 스레드 동작 확인 

int intp2 = 0; // 2번 스레드 동작 확인


// 첫 번째 스레드에 돌아갈 프로그램

void *do_work_one(void *pParam)

{

while(1)

{

sem_wait(&sem1); // 세마포어 1번 카운터 감소 카운터가 0이면 무시


pthread_mutex_lock(&mutex1); // 1번뮤텍스 lock

pthread_mutex_lock(&mutex2); // 2번뮤텍스 lock

intp1++; // 값 증가

pthread_mutex_unlock(&mutex2); // 2번뮤텍스 unlock

pthread_mutex_unlock(&mutex1); // 1번뮤텍스 unlock


sem_post(&sem2); // 세마포어 2번 카운터 증가

}


pthread_exit(0);

}


// 두 번째 스레드에 돌아갈 프로그램

void *do_work_two(void *pParam)

{

while(1)

{

sem_wait(&sem2); // 세마포어 2번 카운터 감소 카운터가 0이면 무시


pthread_mutex_lock(&mutex2); // 2번뮤텍스 lock

pthread_mutex_lock(&mutex1); // 1번뮤텍스 lock


intp2++; // 값 증가

pthread_mutex_unlock(&mutex1); // 1번뮤텍스 unlock

pthread_mutex_unlock(&mutex2); // 2번뮤텍스 unlock


sem_post(&sem1); // 세마포어 1번 카운터 증가

}


pthread_exit(0);

}


int main(int argc, char* argv[])

{

pthread_t p_thread1; // 스레드 구조체1

pthread_t p_thread2; // 스레드 구조체2


pthread_mutex_init(&mutex1, NULL); // 스레드 초기화

pthread_mutex_init(&mutex2, NULL); // 스레드 초기화


sem_init(&sem1, 0, 1); // 세마포어 초기화 카운터값 1

sem_init(&sem2, 0, 0); // 세마포어 초기화 카운터값 0


pthread_create(&p_thread1, NULL, do_work_one, NULL); // 스레드 생성

pthread_create(&p_thread2, NULL, do_work_two, NULL); // 스레드 생성


while(1)

{

printf("first = %d\tsecond = %d\n", intp1, intp2); // 출력으로 쓰레드 동작 확인하기


Sleep(400); // 관찰을 위한 Sleep

}


pthread_mutex_destroy(&mutex1); // 1뮤텍스 해제

pthread_mutex_destroy(&mutex2); // 2뮤텍스 헤제


sem_destroy(&sem1); // 세마포어 해제

sem_destroy(&sem2); // 세마포어 해제


return 1;

}


전에 쓴 교착상태 예제소스를 세마포어를 추가하여 회피시키기

'운영체제론' 카테고리의 다른 글

세마포어를 사용해서 뮤텍스 교착상태 회피하기 (2)  (0) 2015.01.06
교착상태 예제 (3)  (0) 2015.01.06
교착상태 예제 (2)  (0) 2015.01.06
교착상태 예제  (0) 2015.01.06
교착상태(Deadlock)  (0) 2015.01.05
:

교착상태 예제 (2)

운영체제론 2015. 1. 6. 11:15

#include <stdio.h>

#include <Windows.h>


int g_A = 0;

int g_B = 0;


CRITICAL_SECTION g_csA; // 크리티컬섹션 A

CRITICAL_SECTION g_csB; // 크리티컬섹션 B


// 실행될 스레드 1

unsigned int NewThread01(void* pParam)

{

while(1)

{

EnterCriticalSection(&g_csA); // 크리티컬섹션 A

EnterCriticalSection(&g_csB); // 크리티컬섹션 B


g_A++;

g_B++;


LeaveCriticalSection(&g_csB); // 크리티컬섹션 B 해제

LeaveCriticalSection(&g_csA); // 크리티컬섹션 A 해제


Sleep(50); // 관찰을 위한 Sleep

}

}


// 실행될 스레드 2

unsigned int NewThread02(void* pParam)

{

while(1)

{

EnterCriticalSection(&g_csB); // 크리티컬섹션 B

EnterCriticalSection(&g_csA); // 크리티컬섹션 A


g_B++;

g_A++;


LeaveCriticalSection(&g_csA); // 크리티컬섹션 A 해제

LeaveCriticalSection(&g_csB); // 크리티컬섹션 B 해제


Sleep(50); // 관찰을 위한 Sleep

}

}


int main(int argc, char* argv[])

{

InitializeCriticalSection(&g_csB); // 크리티컬섹션 B 초기화

InitializeCriticalSection(&g_csA); // 크리티컬섹션 A 초기화


CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)NewThread01, 0, 0, NULL); // 스레드01 생성

CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)NewThread02, 0, 0, NULL); // 스레드02 생성


while(1)

{

printf("A : %d\tB : %d\n", g_A, g_B);


Sleep(500); // 관찰을 위한 Sleep


}


DeleteCriticalSection(&g_csA); // 크리티컬섹션 A 삭제

DeleteCriticalSection(&g_csB); // 크리티컬섹션 B 삭제


return 1;

}



흔히 검색하면 나오는 크리티컬색션을 이용한 교착상태 예제


기본적으로 데드락을 거는 방식은 뮤텍스랑 똑같음;;;


교착상태 해결방법은 1번 스레드와 2번 스레드의 A,B 락 순서를 똑같이 해주면 교착상태에 빠지지 않는다

:

교착상태 예제

운영체제론 2015. 1. 6. 10:46

#include <stdio.h>

#include <pthread.h>

#include <Windows.h>


pthread_mutex_t first_mutex  = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_t second_mutex = PTHREAD_MUTEX_INITIALIZER;


int firstint = 0;

int secondint = 0;


// 첫 번째 스레드에 돌아갈 프로그램

void *do_work_one(void *pParam)

{

while(1)

{

pthread_mutex_lock(&first_mutex); // 1번뮤텍스 lock

pthread_mutex_lock(&second_mutex); // 2번뮤텍스 lock


firstint++;


pthread_mutex_unlock(&second_mutex); // 2번뮤텍스 unlock

pthread_mutex_unlock(&first_mutex); // 1번뮤텍스 unlock

}


pthread_exit(0);

}


// 두 번째 스레드에 돌아갈 프로그램

void *do_work_two(void *pParam)

{

while(1)

{

pthread_mutex_lock(&second_mutex); // 2번뮤텍스 lock

pthread_mutex_lock(&first_mutex); // 1번뮤텍스 lock


secondint++;

pthread_mutex_unlock(&first_mutex); // 1번뮤텍스 unlock

pthread_mutex_unlock(&second_mutex); // 2번뮤텍스 unlock

}


pthread_exit(0);

}


int main(int argc, char* argv[])

{

int thr_id1; // 스레드 id

int thr_id2; // 스레드 id

pthread_t p_thread; // 스레드 구조체

int thrfirst  = 1; // 1번 스레드 구분숫자

int thrsecond = 2; // 2번 스레드 구분숫자


thr_id1 = pthread_create(&p_thread, NULL, do_work_one, (void*)thrfirst);

thr_id2 = pthread_create(&p_thread, NULL, do_work_two, (void*)thrsecond);


while(1)

{

printf("first = %d\tsecond = %d\n", firstint, secondint); // 출력으로 쓰레드 동작 확인하기


Sleep(500); // 관찰을 위한 Sleep

}


pthread_mutex_destroy(&first_mutex); // 1뮤텍스 해제

pthread_mutex_destroy(&second_mutex); // 2뮤텍스 헤제


return 1;

}







pthread.h는 유닉스/리눅스 상에서 쓰이는 헤더인데


잘 검색해보면 윈도우용 dll lib h를 받을 수 있음


안쓰고 뮤텍스를 사용하는것도 가능한데 닷넷프레임워크 규칙에 따름. 이건 MSDN에서 검색

: