'운영체제론'에 해당되는 글 7건

  1. 2015.01.07 윈도우즈 크리티컬섹션, 뮤텍스, 이벤트, 세마포어
  2. 2015.01.06 세마포어를 사용해서 뮤텍스 교착상태 회피하기 (2)
  3. 2015.01.06 교착상태 예제 (3)
  4. 2015.01.06 세마포어를 사용해서 뮤텍스 교착상태를 회피하기
  5. 2015.01.06 교착상태 예제 (2)
  6. 2015.01.06 교착상태 예제
  7. 2015.01.05 교착상태(Deadlock)

윈도우즈 크리티컬섹션, 뮤텍스, 이벤트, 세마포어

운영체제론 2015. 1. 7. 16:06

윈도우즈 에서의 크리티컬섹션, 뮤텍스, 이벤트, 세마포어







정리!

:

세마포어를 사용해서 뮤텍스 교착상태 회피하기 (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에서 검색

:

교착상태(Deadlock)

운영체제론 2015. 1. 5. 10:41

교착상태


서로 다른 프로세스가 각자 상대방이 자원을 내놓을때까지 작업을 멈추고 기다리는 상태




교착상태의 필요조건


1971년에 E. G. 코프만 교수는 교착상태가 일어나려면 다음과 같은 네 가지 필요 조건을 충족시켜야 함을 보였다.


상호배제(Mutual exclusion) : 프로세스들이 필요로 하는 자원에 대해 배타적인 통제권을 요구한다.

점유대기(Hold and wait) : 프로세스가 할당된 자원을 가진 상태에서 다른 자원을 기다린다.

비선점(No preemption) : 프로세스가 어떤 자원의 사용을 끝낼 때까지 그 자원을 뺏을 수 없다.

순환대기(Circular wait) : 각 프로세스는 순환적으로 다음 프로세스가 요구하는 자원을 가지고 있다.


이 조건 중에서 한 가지라도 만족하지 않으면 교착 상태는 발생하지 않는다. 이중 순환대기 조건은 점유대기 조건과 비선점 조건을 만족해야 성립하는 조건이므로, 위 4가지 조건은 서로 완전히 독립적인 것은 아니다.


by 위키피디아



상호배제 : 한번에 한 프로세스만이 하나의 자원을 사용할 수 있고, 다른 프로세스는 그 자원이 반환될 때까지 기다려야 한다.


점유대기 : 프로세스는 최소한 하나의 자원을 점유한 채로 다른 프로세스에 의해 점유된 자원을 얻기위해 대기해야 한다.


비선점 : 자원들을 선점할 수 없어야 함. 자원이 강제적으로 방출될 수 없고, 점유하고 있는 프로세스가 테스크를 종료한 후 그 프로세스에 의해 자발적으로 방출해야 한다.


순환대기 : 대기 프로세스의 집합에서 각각의 프로세스가 다음 프로세스가 가지고 있는 자원을 얻기위해 대기하고 있고, 마지막 프로세스는 처음의 프로세스가 가진 자원을 얻기위해 대기하고 있어야 한다.





교착상태의 관리 및 처리방법론


현재의 대부분의 운영 체제들은 교착 상태를 막는 것은 불가능하다. 교착 상태가 발생하면 여러 운영 체제들은 제각기 다른 비표준 방식들로 이러한 교착 상태에 대응한다. 대부분의 접근들은 4가지 코프먼 조건들 가운데 하나(특히 4번째 것)를 막음으로써 동작한다. 주요 접근 방식은 다음과 같다.


교착 상태의 예방

  상호배제 조건의 제거 : 교착 상태는 두 개 이상의 프로세스가 공유 불가능한 자원을 사용하니 발생하는 것이므로 공유 불가능한, 즉사 상호 배제 조건을 제거하면 교착 상태를 해결할 수 있다.

  

  점유와 대기 조건의 제거 : 한 프로세스에 수행되기 전에 모든 자원을 할당시키고 나서 점유하지 않을 때에는 다른 프로세스가 자원을 요구하도록 하는 방법이다. 자원 과다 사용으로 인한 효율성, 프로세스가 요구하는 자원을 파악하는 데에 대한 비용, 자원에 대한 내용을 저장 및 복원하기 위한 비용, 기아상태, 무한 대기 등의 문제점이 있다.


  비선점 조건의 제거 : 비선점 프로세스에 대해 선점 가능한 프로토콜을 만들어 준다.


  환형 대기 조건의 제거 : 자원 유형에 따라 순서를 매긴다.


이 교착 상태의 해결 방법들은 자원 사용의 효율성이 떨어지고 비용이 많이 드는 문제점이 있다.


교착 상태의 회피

교착 상태의 무시

교착 상태의 발견


by 위키피디아


1. 시스템이 결코 교착상태가 되지 않도록 하기 위해 교착상태를 예방하거나 회피하는 프로토콜을 사용
  교착상태 예방(prevention) 기법 : 교착 상태의 필요조건중 적어도 하나가 성립하지 않도록 자원 요청에 대해 제한을 둠
  교착상태 회피(avoidance) 기법 : 시스템은 현재 요청이 만족되는지 혹은 지연해야 하는지를 결정하기 위해 현재 사용 가능한 자원들과 각 프로세스에 할당된 자원 프로세스의 요청과 해제를 고려하는 방법

2. 시스템이 교착상태가 되도록 허용한 다음에 회복시키는 방법
  교착상태 탐지 알고리즘, 교착상태로부터의 회복 알고리즘

3. 문제를 무시하고, 교착상태가 시스템에서 결코 발생하지 않는 척 한다.
  성능저하 -> 시스템 중단 -> 인위적인 재시작
  대부분의 운영체제에서 선택 된 방법


: