삽질의 현장/- 윈도우 시스템

#024_WIndow_System_커널 모드 동기화 객체_세마포어

shovelman 2015. 9. 25. 01:19


안녕하세요 삽잡이입니다.


이번 시간에는 커널 모드 동기화 객체중 세마포어에 대해서 알아보려고 합니다.



매개변수로는 다른 커널 오브젝트들과 같이 처음에는 속성을 받습니다.

그 다음으로는 자원의 개수들을 할당 받습니다.

그러니까... 두번째 인자로는 사용가능한 자원의 개수, 그 다음으로는 최대 자원의 개수

마지막 인자로는 세마포어의 이름을 인자로 받습니다.


키를 쥐고 있다가, 필요가 없어지면 반환을 해야하듯이,

세마포어에서는 ReleaseSemaphore 함수를 사용합니다.


 

키를 반환하면 카운트를 증가시킵니다.

즉, CreateSemaphore 에서 생성한 키의 개수를 사용한 다음에 다시 반납하니 

숫자를 증가 시키겠죠...


뭔말이냐하면... 세마포어는 소유 개념이 없습니다.

즉, 뮤텍스와 조금 개념이 다르다는 것입니다.


자원을 소유가 아닌, 할당받아 사용한다고 생각하면 됩니다.

예를 들어서 3개를 최대 사용 가능한 자원의 개수라고 한다면 3개의 키만을 할당 받는 것입니다.


만약, 자원의 개수가 3이고, 쓰레드는 4개가 동작하고 있다고 해봅시다...

동작을 하는데 Release를 해주지 않으면 키를 내놓지 않는 것이기 때문에

쓰레드 하나가 제대로 동작하지 않게 됩니다.

왜냐 키를 쥐고있지 않으니깐 말입니다...


세마포어는

Rlease 하여 자원이 비어버리면, Wait하고 있던 쓰레드가 가져가서 사용하게 됩니다.

그리고 또 누군구 자원을 해제해줄 때 까지 자원을 할당받지 못하기 때문에

Blocking 상태에 있게 됩니다.


뮤텍스의 경우에는 외부에서 자원 해제를 할 수 없었습니다.

오직 비신호 상태의 뮤텍스를 소유한 쓰레드만이 Release 할 수 있었습니다.

세마포어는 소유권 개념이 없기 때문에 외부에서 해제해줄 수 있습니다.

단, 세마포어가 사용할 수 있는 자원이 3개라면 그 사실을 인지하고 있어야합니다.


배열에 초기화 되어있는 인덱스를 벗어나면 쓰레기 메모리를 참조하게 되듯이,

세마포어도 다르지 않습니다. 즉, 열어 놓은 자원의 개수만큼 사용하도록 신경을 써야한다는 것입니다.


아무튼... 세마포어는 뮤텍스와 다릅니다...

자신이 됬던 누가 됬던 자원을 Release해서 사용가능하도록 해야합니다.

어느 누구도 Release 해주지 않게 되면 사용할 수 없게 됩니다.


결론적으로 처음에는 어떤 자원도 사용 가능하도록 만들어져있지 않는데,

Release를 통해 사용가능 하도록 만들어주면 쓰레드가 사용할 수 있게 됩니다.

그리고 그 쓰레드가 Release를 해주게 되면 다른 쓰레드가 사용할 수 있게 됩니다.


자신의 것을 Release 해주는 것이 아니라 하나를 사용가능하도록 만들어 주는 것입니다.

그 코드를 이와 같이 사용할 수 있습니다.


ReleaseSemaphore(handle, 1, NULL);


왜냐, 세마포어는 소유 개념을 가지고 있는 것이 아니기 때문입니다.


음... 이전 동기화 객체들 처럼 하나의 열쇠를 생성하고 가져가는 쓰레드만 사용하는 것이 아니라,

열쇠를 여러개 두고 쓰레드들이 가져갈 수 있게 해주는 것입니다...


세마포어를 사용하는 예를 찾아볼까요...

우리가 다운로드를 할 때에 100개를 하더라도, 3개 정도가 동작하는 것을 볼 수 있습니다.

왜냐, 다운로드는 독립적으로 동작하기 때문에 쓰레드 방식으로 동작하는데,

동작 가능 개수는 세마포어로 조절하는 것이기 때문입니다.


지금까지 세마포어에 대해 알아봤습니다.

이상 삽잡이였습니다!