autohotkey) Mutex에 대해서
http://www.autohotkey.pe.kr/bbs/board.php?bo_table=tip&wr_id=723
안철수연구소 우회법 알려드리겠습니다.
간단하게 말해서 그쪽 프로그램은 각 프로그램의 외부변수인 mutent를 체크해서 프로그램을 막습니다.
뮤텍스 네임을 바꾸는 겁니다.
소스파일 다운받아서
hook.cpp 에서
#define KEYBD_MUTEX_NAME "AHK Keybd"
#define MOUSE_MUTEX_NAME "AHK Mouse"
이렇게 뮤텍스이름 정의되잇는 부분을 찾아서 마음대로 바꾼다음에 컴파일시켜서 당신만의 오토핫키를 만드세요.
그럼 우회됩니다.
자기프로그램 뮤텍스 해제는 ReleaseMutex
You could use DllCall to call CreateMutex().
쓰레드(Thread)는 멀티프로세스가 지원되는 OS에서 실행의 최소 단위입니다.
쓰레드가 모여서 하나의 프로세스를 구성하지요... 그러니까 프로세스를 기동시키면 한개 이상의 쓰레드가 기동되는것을 의미하는것죠.
하나의 프로세스에 여러개의 쓰레드를 기동시키기도 합니다.
프로세스는 말 그데로.. 독립적인 실행의 단위입니다.
대충 프로세스와 쓰레드는 설명이 되었고 Visual C++을 사용하면 동기화에 관련된 몇가지 모듈을 제공합니다.
크리티컬섹션(CriticalSection)
뮤텍스(Mutex)
세마포어(Semaphore)
그 밖에 기타 Event, Overlapped 등을 지원합니다.
동기화(상호배제)에 관해서는 님께서 대충 아신다고 하니.. 그 부분은 설명하지 않고.
크리티컬섹션과 뮤텍스의 차이점과 CreateMutex()에 관해서만 설명드리겠습니다.
크리티컬섹션이나 뮤텍스는 어떻게 보면 기능상 똑같다고 생각하시면 됩니다. 약간은 차이는 나지만 근본적인 차이는 크리티컬섹션은 하나의 프로세스 안에서만 동작하는 것이고 (그러니까 하나의 프로세스안에 여러개의 쓰레드가 있을경우 그 쓰레드들간의 상호배제를 구현하는것이지요) 뮤텍스는 문자열로 뮤텍스의 이름을 지정해 주면 뮤텍스의 이름으로 프로세스간에도 상호배제를 사용할 수 있습니다.
윈도우즈의 뮤텍스와 관련된 함수는 다음과 것들이 있습니다.
HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName);
HANDLE OpenMutex(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSTR lpName);
BOOL ReleaseMutex(HANDLE hMutex);
CreateMutex()함수는 뮤텍스를 생성합니다.
이미 생성된 이름을 갖는 뮤텍스의 핸들을 얻기 위해서는 OpenMutex()를 사용합니다.
뮤텍스의 사용이 끝나서 해당 뮤텍스를 놓아 줄때는 ReleaseMutex()함수를 사용합니다.
위에 원형은 밝히지 않았지만 생성한 뮤텍스를 파괴시킬때는 모든 커널객체가 그렇듯 CloseHandle()함수를 사용합니다.
참고로 신호상태인 뮤택스를 얻기 위해서는 위에서 설명한 대기함수를 사용해야 한다는 것은 짐작하셨겠죠?
이때 CreateMutex()는 이미 다른 프로세스에서 사용하고자 하는 뮤텍스를 생성하였다면 CreateMutex()함수를 호출하지 않고 OpenMutex()를 사용해도 되지만 CreateMutex()함수를 다시 한번 더 호출해도 상관이 없습니다.
CreateMutex()함수의 아큐먼트는 다음과 같습니다.
- lpMutexAttributes : 뮤텍스의 보안 속성을 지정하는 것으로서 주로 상속관계를 지정하기 위해 사용됩니다. 일반적으로는 NULL을 입력합니다.
- bInitialOwner : 뮤텍스를 생성하면서 사용권한을 갖을 것인지를 결정합니다. 즉, TRUE를 입력하면 생성하자 마자 뮤텍스의 사용권한(비신호상태의 뮤텍스 생성)을 갖습니다. FALSE를 입력할 경우 뮤텍스만 생성하기만(신호상태의 뮤텍스 생성) 하고 실제 사용권한을 얻을때는 대기함수를 사용해야 합니다.
- lpName : 뮤텍스에 이름을 문자열로 지어 줍니다. 이름이 지정된 뮤텍스를 만듦으로서 이 이름을 아는 다른 프로세스와의 동기화를 할 수 있습니다. 하나의 프로세스에서만 동기화 방식으로 뮤텍스를 사용한다면 NULL을 입력하여 이름을 지어 주지 않을 수도 있습니다. 참고 이름을 지어준 뮤텍스를 명명된 뮤텍스(named mutex)라고 합니다.
CreateMutex()함수는 생성한 뮤텍스의 핸들을 리턴합니다. 만약 생성하려는 뮤텍스의 이름으로 이미 뮤텍스가 생성되어 있는 경우는 해당 뮤텍스 핸들을 리턴하고 GetLastError()로는 ERROR_ALREADY_EXISTS값을 얻을 수 있습니다. 만약 생성되어 있는 뮤텍스에 접근할 수 있는 권한이 없는 경우(ERROR_ACCESS_DENIED) NULL을 리턴합니다. 구체적인 원인을 알기 위해서는 GetLastError()함수를 호출하여 알 수 있습니다. 만약 EROR_ACCESS_DENIED일 경우는 OpenMutex()함수를 사용하여야 합니다.
OpenMutex()함수의 아큐먼트는 다음과 같습니다.
- dwDesiredAccess : 접근속성
- bInheritHandle : 상속옵션
- lpName : 지정된 뮤텍스의 이름
OpenMutex()함수는 이름이 지정된 뮤텍스의 핸들의 핸들을 리턴합니다. 만약 지정된 이름의 뮤텍스가 없는 경우는 NULL을 리턴하고 GetLastEror()함수는 ERROR_FILE_NOT_FOUND값을 리턴합니다.
일반적으로 OpenMutex()함수는 잘 사용하지 않습니다. 왜냐하면 CreateMutex()함수로 새로운 뮤텍스를 생성할 수도 이미 생성된 뮤텍스의 핸들을 얻을 수도 있기 때문이죠.
위에서 이야기 한대로 뮤텍스에 보안 속성을 설정한 경우 OpenMutex()를 사용하기도 합니다.
ReleaseMutex()함수는 잡았던 뮤텍스(비신호상태의 뮤텍스)를 다시 놓아주는(신호상태로 만들어 주는) 함수입니다.
아큐먼트는 hMutex에 뮤텍스 핸들을 넣어 줍니다. 놓아주기에 성공하면 TRUE를 실패하면 FALSE를 리턴합니다.
뮤텍스 설명에 관한 출처...
http://blog.naver.com/herryjoa?Redirect=Log&logNo=110028833001
http://blog.naver.com/kimgudtjr?Redirect=Log&logNo=140107517776
그리고 위에 설명 해 놓은것은 API이고..
MFC를 사용하신다면 CMutex Class를 사용하시면 편리합니다...
사용방법은 비슷하지만. CMutex Class가 훨씬 사용하기가 편합니다....