728x90

이름있는 뮤텍스(Named Mutex)기반의 프로세스 동기화

뮤텍스나 세마포어를 생성할 때 오브젝트에 이름을 붙여줄 수 있다. 뮤텍스에 이름을 붙여 생성할 경우 "이름있는 뮤텍스(Named Mutex)"라 하고, 세마포어에 이름을 붙여 생성할 경우 "이름있는 세마포어(Named Semaphore)"라고 한다.

 

이름있는 뮤텍스 기반의 동기화는 서로 다른 프로세스 영역에 존재하는 쓰레드를 동기화 시키는데 사용된다.

 

뮤텍스는 커널오브젝트 이므로 모든 프로세스들이 접근할 수 있다. 그러나 뮤텍스의 핸들값은 뮤텍스를 생성한 프로세스만이 소유하고 있고 핸들값을 다른 프로세스에 넘겨줘도 핸들테이블에 등록되어있지 않아 의미가 없다. 핸들값에 대한 정보 즉 실제 커널오브젝트를 가리키는 핸들값은 핸들 테이블에 등록되어 있는데, 이 핸들 테이블은 프로세스 별로 독립적이다.

 

A프로세스에서 이름있는 뮤텍스를 생성 하고 실행중이다. 이후 B프로세스가 뮤텍스의 이름을 설정하고 OpenMutex함수를 호출하여 실행하면 A프로세스가 소유하고 있는 뮤텍스의 핸들을 얻을 수 있다.

B프로세스가 OpenMutex함수를 호출하여 뮤텍스를 소유할려고 하지만 A프로세스가 이미 소유하고 있기 때문에 A프로세스가 뮤텍스를 반환할 때까지 B프로세스는 실행을 멈춘다. A프로세스가 뮤텍스를 반환하면, B프로세스는 뮤텍스를 얻어서 실행하게 된다.

 

위와같은 원리로 이름있는 뮤텍스를 사용하면 서로 다른 프로세스에 존재하는 쓰레드 간에도 동기화가 가능하다.

 

OpenMutex 함수 선언

HANDLE OpenMutex(

    DWORD dwDesiredAccess,

    BOOL bInheritHandle,

    LPCTSTR lpName

);

1.dwDesiredAccess : 이름 있는 뮤텍스로의 접근 권한을 지정하는 것이다. 전달인자로 MUTEX_ALL_ACCESS을 전달해서 접근할 수 있는 권한을 요청해야 한다.

2.hInheritHandle : 핸들의 상속 유무를 결정하기 위한 전달인자 이다.

3.lpName : 얻고자 하는 핸들 정보의 커널 오브젝트 이름을 전달한다. 여기로 전달하는 이름과 일치하는 이름을 지니는 뮤텍스가 존재한다면, 이 뮤텍스의 핸들이 반환된다. 핸들 테이블에 이에 대한 정보도 추가된다.

 

 뮤텍스의 소유와 WAIT_ABANDONED

 

WaitForSingleObject 함수의 반환값중 WAIT_ABANDONED라는 것이 있다.

 

뮤텍스의 경우 획득한 쓰레드가 반환해야 하지만 세마포어는 그렇지 않다. 즉 세마포어의 경우 세마포어를 획득하는 쓰레드와 반환하는 쓰레드가 달라도 문제가 되지 않는다.

 

뮤텍스는 획득한 쓰레드가 직접 반환하는 것이 원칙이다. 본인만이 반환할 수 있다. 그러나 세마포어와 그 이외의 동기화 오브젝트는 마치 도서 대여점처럼 대신 다른 누군가가 반환해 줘도 문제가 되지 않는다.

 

쓰레드 A가 오브젝트인 뮤텍스를 소유하고 있다. 쓰레드B는 쓰레드 A가 뮤텍스를 반환하기를 기다린다. 그러나 예상치 못한 문제로 쓰레드 A가 뮤텍스를 반환하지도 않고 사라졌다. 이러한 경우 Windows는 정상적인 방법으로 반환이 불가능한 뮤텍스를 대신 반환해주고, 다음 대기자인 쓰레드 B가 뮤텍스를 소유할 수 있도록 도와준다. 이 때 쓰레드 B는 WAIT_ABANDONED값을 반환받게 된다.

728x90

+ Recent posts