LISTORY

[윈도우즈 시스템 프로그래밍] 이벤트(Event) 더하기 뮤텍스(Mutex) 본문

IT/윈도우 프로그래밍

[윈도우즈 시스템 프로그래밍] 이벤트(Event) 더하기 뮤텍스(Mutex)

LiStoryTeller 2018. 9. 21. 21:30


뇌를 자극하는 윈도우즈 시스템 프로그래밍 책 관련 유투브 강의 내용 정리이다.


이번 시간은 저번 시간에 이어, 이벤트 예제를 다뤄보도록 하겠다.


YouTube 주소 : 이벤트(Event) 더하기 뮤텍스(Mutex)



이벤트(Event) 더하기 뮤텍스(Mutex)


이벤트 기반 동기화 예제로 예제는 StringEvent.cpp 를 다루겠다. 


수동 리셋 모드 이벤트 관련한 예제는 StringEvent2.cpp, StringEvent3.cpp를 보도록 하겠다.


예제를 자세히 보려면 책으로 확인하길 바란다.



StringEvent.cpp 먼저 보도록 하겠다.



이벤트는 수동 리셋 모드로 생성하였다.


또한 생성과 동시에 non-signaled 상태로 설정되도록 하였다.


이름없는 Event는 13장 강의를 확인하면 알 수 있다.



이벤트를 생성한 다음엔 쓰레드를 생성하였다.


main은 생산자 쓰레드의 역할을 하고 있다. 지금 생성하는 쓰레드는 소비자 역할을 할 쓰레드이다.


중요한건 생산자 쓰레드가 소비자 쓰레드의 생성 시기를 알려주는 것이다.


일단, 소비자 쓰레드의 기능을 알려주는 OutputThreadFunction 함수를 보자



제일 먼저 시작되자마자 하는 일은 hEvent가 Signaled 상태가 되도록 기다리는 것이다.


즉, 데이터가 입력되기를 기다리고 있다.


다시 main 함수를 보자



main 쓰레드는 데이터를 입력 받고, 이벤트를 Signaled 상태로 바꿔주고 있다.


바꾸고 나서는 쓰레드가 실행할 수 있도록 WaitForSingleObject 함수를 다시 호출하고 있다.


이는 main이 생성한 쓰레드보다 미리 끝나서는 안되기 때문이다.


즉, 소비자 쓰레드가 생성자 쓰레드의 SetEvent() 함수를 기다렸다가 입력받은 데이터를 출력시키는 간단한 내용이다.


이 모델은 수동 모드로 만들었지만 실제로는 자동으로 해도 상관없는 내용이다.



이제 StringEvent2.cpp 모델을 살펴보도록 하겠다.


이 모델은 두개의 쓰레드를 생성한다.


즉, 앞선 모델과 달리 하나의 스레드가 더 등장한다.



새롭게 등장한 스레드는 CountThreadFunction이다.


코드는 위의 모델과 비슷하므로 CountThreadFunction이 어떤 역할을 하는지만 살펴보겠다.



첫번째 함수는 입력받은 데이터를 출력하는 역할을 한다.


두번째 함수는 입력 데이터의 길이를 계산하여 출력하는 역할을 한다.


생성된 두개의 쓰레드는 모두 생성된 동시에 하나의 이벤트를 관찰한다.


또한, 두개 모두 입력된 데이터가 들어와야 실행이 가능하다.


main은 데이터를 입력받으면 동일하게 SetEvent() 함수를 호출한다.


이 함수가 호출되는 순간 동시에 두 쓰레드가 작동한다.


이 코드를 실행하면 우리가 원하는 결과가 나올 수 있다.


하지만 여기서 문제되는게 있다.


우리가 원하는건 데이터와 데이터 길이가 순서대로 출력되는 것이다.


하지만 이 두개의 문장이 섞여나올 수 있다.


우리가 보통 임계영역이다 하면 일반적으로 메모리 접근과 하나의 코드 블럭만 생각하는 경향이 있다.


하지만 이 예제는 각각 쓰레드의 데이터의 출력 부분이 콘솔이라는 메모리 영역에 데이터를 출력하는 과정에서 생기는 문제를 보여준다.


즉, 두개의 코드 블럭 각각을 임계 영역으로 처리해야한다.


여기서의 문제점은 실행순서는 동기화 했지만 콘솔 영역에 대한 접근 동기화를 해주지 않은 것이다.


다시 말하자면 콘솔에 동시 접근하여 생긴 문제이다.


결론적으로 보자면 다음과 같다.


임계 영역

 - 하나의 메모리 블럭으로 나타날 수 있지만 둘 이상의 메모리 블럭이 하나의 임계 영역을 형성할 수도 있다.



StringEvent3.cpp는 이 모든 문제를 해결한 모델이다.


확장한 부분의 코드만 살펴보도록 하겠다.



임계영역 부분을 WaitForSingleObject와 mutex를 이용하여 동기화 시켜주고 있다.





Comments