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

#023_WIndow_System_커널 모드 동기화 객체_뮤텍스

shovelman 2015. 9. 25. 01:19


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

이번 시간에는 커널 모드에서 동기화 하는 방법들을 소개하려고 합니다.


우선 커널 모드에서 동기화를 수행하기 위해서는 커널 오브젝트가 필요합니다.

즉, 커널 모드 동기화 객체들이 커널 오브젝트라는 것입니다.

따라서 커널 모드 동기화 객체들은 핸들을 보관해야할 필요성이 있습니다.


커널 모드에서 동기화를 하는 것은 어플리케이션 모드보다 더 느릴 수 있습니다.

왜냐, 커널 모드로 갔다가 유저모드로 왔다가... 왔다리 갔다리를 해야하기 때문입니다.


아무튼... 함수 이름이 다를 뿐이지, 

사용방법은 유저모드에서 동기화를 수행했던 방법과 비슷합니다.


우선, Mutex에 대해서 알아보도록 하겠습니다.

뮤텍스를 사용하기 위해서는 우선 뮤텍스를 생성해줘야합니다.



해당 함수를 사용하여 뮤텍스를 생성하게 되면,

뮤텍스는 커널 오브젝트로써 핸들을 반환해줍니다.


뮤텍스의 핵심은 소유권입니다.

뮤텍스를 생성하면 신호, 비신호 상태를 가질 수 있습니다.


뮤텍스는 처음 생성할 때 신호, 비신호 상태의 여부를 경정하여 생성할 수 있습니다.

참고로, 신호 상태로 만드는 방법은 어떠한 쓰레드도 소유하고 있지 않게 만들면 됩니다.

그렇다면, 어떤 쓰레드가 뮤텍스를 소유하게 되면 해당 뮤텍스는 비신호 상태가 된다는 것을 알 수 있습니다.


CreateMutex 함수의 각 매개변수에 대해 알아보자면,

첫 번째 인자로 상속 여부를 결정하는 보안속성,


두 번째 인자로 소유권을 결정합니다.

두번째 인수는 owner가 뮤텍스를 가지도록 할것인지, 말것인지에 대해서 결정하는 인수입니다.

즉, 뮤텍스를 만든 놈이 소유할지 말지에 대해서 결정하는 것입니다.

따라서 TRUE로 설정하게 된다면, Primary Thread가 생성하는 명령을 수행하니,

Primary Thread가 Mutex의 소유권을 가질지 말지에 대해 결정하는 것입니다.


마지막 인자는 이름을 표시하는 것입니다.

커널 오브젝트는 이름을 가질 수 있으며 이름은 ID로 사용됩니다. 

즉, 이름을 지정하면 같은 뮤텍스가 되는 것입니다.

이를 통해 우리는 뮤텍스가 공유될 수 있다는 것을 확인할 수 있습니다.

하나의 뮤텍스를 프로세스간에 여러 쓰레드가 사용할 수 있게 된다는 것이죠...

이름을 갖지 않으면 프로세스 내에서만 사용할 수 있는 뮤텍스가 되는 것이고,

이름을 지정해준다면, ID로 사용되어 동일한 ID로 CreateThread를 호출하면

Create가 아닌 Open이 되는 것입니다.


C언어에서 fopen 함수를 생각해봅시다.

무조건 create, open 기능을 둘다 담당하고 있습니다.

이와 같이 CreateThread 함수는 생성과 열기 기능 두 가지를 모두 소유하고 있습니다.

어찌됬건, 프로세스 간에도 

동기화 오브젝트를 공유하고 동기화 할 수 있다는 사실을 기억하기실 바랍니다.


아무튼...

어떠한 쓰레드도 뮤텍스를 소유하지 않게 되면 신호 상태가 됩니다.

신호상태를 기다리는 함수는 WaitForSingleObject 함수가 있지요...


여기서 잠시 WaitForSingleObject 함수에 대해서 알아봅시다.

이 함수는 지금까지 신호상태를 기다리는 함수라고만 알고 있었습니다.

하지만 해당 함수는 기능을 두 가지 가지고 있습니다.

우선, 해당 함수를 만나면 대기하는 기능을 가지고 있습니다.

그리고, 뮤텍스 같은 동기화 오브젝트의 소유권을 얻는 기능을 가지고 있습니다.

WaitForSingleObject 함수를 만나자 마자 대기할지 안할지에 대해 결정을 내릴 수 있다는 것입니다.


이러한 매커니즘으로 동기화가 수행되는 것입니다.

다시 말씀드리지만... 

동기화란, 동시 작업이 안됩니다. 단 하나처럼 동작해야됩니다.

즉, 한몸처럼 동작해야한다는 것입니다.