2009년 1월 30일 금요일

_SingLeton()과 ProcessExists()함수를 이용한 중복실행 확인의 차이와 분석

AutoIt으로 로더를 만들어 본다며 이리저리 스크립팅을 하다보니 중복실행에 대해 처리하는 방법으로

크게 2가지 방법이 있더군요..
바로 _SingLeton()함수와 ProcessExists()함수 이죠....
이 두 함수의 작용을 보면 다소 차이가 있습니다.
_SingLeton()을 설명하려면 우선 프로그래밍에서 쓰이는 Mutex를 설명해야 할 듯 합니다.
--------------------------------------------------------------------------------------------------------------------

뮤텍스란?

MUTual EXclusion 으로 우리말로 해석하면 '상호 배제'라고 한다.

Critical Section을 가진 Thread들의 running time이 서로 겹치지 않게, 각각 단독으로 실행되게 하는 기술이다.

* Critical Section : 프로그램 상에서 동시에 실행될 경우 문제을 일으킬 수 있는 부분.

만약 어느 Thread에서 Critical Section을 실행하고 있으면 다른 Thread들은 그 Critical Section에 접근할 수 없고 앞의 Thread 가 Critical Section을 벗어나기를 기다려야 한다.

--------------------------------------------------------------------------------------------------------------------


지식인에서 발췌했습니다.


이를 중복 실행 방지에 사용하는 방법이 첫 번째 프로그램이 Critcal Section에 특수한 값을 등록하여 두어, 두 번째 실행된


프로그램에서 Critcal Section에 동일한 값으로 접근하려 하였을 때 접근 권한을 얻지 못하면 프로그램을 종료하거나


종료될 때까지 기다리도록 프로그래밍 하는 것이죠..


여기에 한 가지 중요한 전제가 있는데..... 바로 실행된 프로그램이 동일한 값으로 접근해야 한다는 것입니다.


자.. 다음과 같은 코드를 가진 프로그램이 있습니다.


If _Singleton("TEST") = 0 Then
  MsgBox(0, 'ERROR', '이미 프로그램이 실행중입니다.')
Else
  MsgBox(0, 'OK', '프로그램이 처음 실행되었습니다.')
EndIf

이 소스를 컴파일하여 Test.exe란 실행파일을 얻었습니다.

처음으로 Test.exe를 실행 시키면 "프로그램이 처음 실행되었습니다." 라는 메시지를 얻을 수 있겠죠...

이 상태에서 메시지 박스를 닫지 않은 상태에서 또 Test.exe 프로그램을 실행시킨다면 '이미 프로그램이 실행중입니다.'

라는 메시지를 얻을 수 있을 것입니다.


위 소스를 조금 수정해 보죠....

While 1
  If _Singleton("TEST") = 0 Then
    Exit
  Else
    Run('notepad.exe')
  EndIf
WEnd

컴파일하고 Test.exe를 실행합니다. 처음 Test.exe를 실행하면 노트패드가 실행되겠지만, 두번째 실행할 경우는

노트패드 실행 없이 Test.exe가 종료될 것입니다. 물론 처음 실행된 것은 계속 실행되어 있겠죠...


예제에 조금 더 살을 붙이겠습니다. 우리가 원하는 Test.exe 프로그램은 노트패드가 이미 실행중이라면 더이상

노트패드가 실행되지 않기를 바랍니다. Test.exe를 통하지 않고 실행된 노트패드까지 포함해서 말이죠...

누군가가 [시작]-[모든 프로그램]-[보조프로그램]-[메모장] 메뉴를 통해 노트패드를 실행하고 창을 숨겨두었습니다.

이경우 Test.exe를 실행하면 어떻게 될까요????

Test.exe가 실행되면서 노트패드를 열게 될것입니다. Test.exe 프로그램이 오류를 일으킨 셈이죠...


이럴 경우 사용 할 수 있는 방법이 ProcessExists()함수를 이용하는 방법입니다.


ProcessExists()함수는 인자로 받은 프로세스명 또는 프로세스ID가 이미 실행프로세스 상에 존재할 경우

프로세스ID값을 반환합니다. 프로세스가 존재하지 않는다면 0을 반환하죠....

다음과 아래 예제는 위에서 언급한 문제를 해결한 소스입니다.

If ProcessExists('notepad.exe') = 0 Then
  Run('notepad.exe')

이제 이 소스를 컴파일한 Test.exe파일을 실행하면 이미 메모장이 실행되어 있을 경우 Test.exe는 아무 동작 없이

종료될 것이고 Test.exe를 몇번을 실행하더라도 메모장은 하나만 열려있을 것입니다.



지금까지 언급한 부분은 어떤 방식으로 두 함수가 프로그램의 실행에 대해 접근하느냐 하는 부분을 이야기하고자

한 것입니다.


AutoIt으로 로더 프로그램을 한다는 관점에서 _Singleton()과 ProcessExists()를 사용하는 예를 설명해 보겠습니다.

MS Excel을 포터블화 하기 위해 로더를 만든다고 생각해 보죠...

로더를 실행할 때 레지스트리를 등록하고 프로그램을 실행시키고 프로그램이 종료되면 레지스트리를 삭제하는

작업을 진행하게 됩니다.

엑셀로더를 중복 실행하면 어떻게 될까요.... 레지스트리가 두번 등록되면서 얘기치 않은 오류가 발생할 가능성도

있고.. 먼저 실행되었던 프로그램이 종료 되면서 레지스트리를 삭제하여 두번째 실행된 엑셀 문서를 작성하고 저장하면서

레지스트리에 데이터를 남기고 프로그램이 종료될 가능성도 있습니다.

또는 레지스트리 데이터를 백업하고 삭제하도록 한다면 레지스트리 백업 정보 중 일부가 사라질 수도 있겠지요..


이때 _Singleton()함수를 이용해 로더가 이미 실행 중일경우 엑셀 실행파일만 실행하고 로더는 종료할 수 있도록 하고

처음 실행된 로더는 ProcessExists()함수를 통해 엑셀이 모두 종료되면 레지스트리 정보를 백업하고 삭제하도록 하면

될 것입니다.

다음 예로 V3를 포터블화 했다고 가정해 보겠습니다. V3가 실행되면 항상 동작해 있는 서비스 프로그램이 있습니다.

이 경우 서비스 프로그램이 중복실행될 필요가 없으며 중복 실행으로 인해 문제가 발생할 수 있습니다.

이때는 _Singleton()함수 없이 ProcessExit()를 통해 서비스 프로그램이 실행 중인지 확인하고 이미 실행 중이라면

로더를 바로 종료하는 것이 좋은 방법이 될겁니다.


이렇듯 프로그램의 성격에 따라 _Singleton()과 ProcessExists()를 알맞게 사용해 중복실행 방지 방법을 달리 하는것이

더욱 안정적인 로더 프로그램 만들기에 도움이 됩니다.

강좌라기 보다는 저 또한 중복실행 방지에 대한 생각의 정리가 필요해 작성해본 허접한 글이었습니다...

긴 글 읽으시느라 고생 많으셨습니다~~~

댓글 없음:

댓글 쓰기