자식 프로세스에게 핸들 정보를 전달하기 위해 파일을 활용하는 방법은
잘 동작하긴 하나 촌스럽고 안정적이지 않은 방식이다.
이보다는 프로세스 생성 시 메인 함수의 매개변수를 활용하는 것이
훨씬 안정적이다.
이번에는 프로세스 환경변수를 활용하는 방법을 알아보겠다.
프로세스별로 별도의 메모리 공간에 문자열 데이터를 저장하고 관리할 수
있도록 되어 있으며, 문자열의 구조는 다음과 같고, 이를 환경 변수라 한다.
key = value
[key,value] 의 형태를 띠므로 둘 이상의 데이터를 관리하기가 좋으며,
부모 프로세스는 자식 프로세스의 환경변수를 등록할 수도 있고,
그냥 부모 프로세스의 환경 변수를 상속시킬 수 있다.
값을 참조하는 과정에서 key와 value를 따로 분리시킬 필요도 없는데,
이는 다음 함수를 통해 우리가 쉽게 값을 등록 및 참조할 수 있기 때문이다.
다음은 프로세스 환경변수를 등록할 때 사용하는 함수다.
BOOL SetEnvironmentVariable(
LPCTSTR lpName,
LPCTSTR lpValue
);
1) Key 에 해당하는 값을 지정하며, 이후 Key를 통해 value 값을 참조하게 된다.
2) value 에 해당하는 값을 지정한다.
다음은 위 함수를 통해서 등록한 환경변수를 참조할 때 사용하는 함수이다.
DWORD GetEnvironmentVarible(
LPCTSTR lpName,
LPTSTR lpBuffer,
DWORD nSize
);
1) Key를 전달하며, Key에 해당하는 value를 얻게 된다.
2) value 값을 저장하기 위한 메모리의 주소를 지정한다
3) lpBuffer 가 가리키는 메모리의 크기를 지정한다
이 함수는 성공시에 lpBuffer 에 저장된 문자열의 길이를 반환한다.
다음 예제는 위의 두 함수의 사용법을 보여준다.
부모 프로세스가 자신의 환경변수를 등록하고, 자식 프로세스에게 상속시켜
자식 프로세스가 값을 확인하는 간단한 예제이다.
우선 환경변수를 설정하는 부모 프로세스부터 보자.
int _tmain(int argc, TCHAR* argv[])
{
SetEnvironmentVariable(
_T("Good"), _T("Morning")
);
SetEnvironmentVariable(
_T("Hey"), _T("Ho")
);
SetEnvironmentVariable(
_T("Big"), _T("Boy")
);
STARTUPINFO si={0,};
PROCESS_INFORMATION ps={0,};
si.cb=sizeof(si);
CreateProcess(
NULL, _T("EnvChild"), NULL, NULL, FALSE,
CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
NULL, //이게 NULL이면 부모 프로세스에 등록되어 있는 환경변수를 등록하겠다 라는 의미다.
NULL,
&si, &pi
);
CloseHandle( pi.hProcess);
CloseHandle( pi.hThread);
return 0;
}
------------정리---------------------------------------------------------------------------
1. 핸들 테이블
커널 오브젝트와 핸들 사이에 핸들 테이블이 존재한다.
이로서 핸들을 참조하여 특정 커널 오브젝트를 가리킬 수 있다.
2. 핸들과 핸들 테이블
핸들 테이블은 프로세스별로 독립적이다. 그리고 숫자가 핸들로서 의미를 지니기 위해서는
해당 숫자가 핸들 테이블에 등록되어야 한다. 등록되는 순간부터 핸들이라 할 수 있으며,
이 핸들을 통해 커널 오브젝트에 접근하는 것이 가능하다.
3. 핸들의 상속
핻늘은 자식 프로세스를 생성하는 과정에서 상속할 수 있다.
핸들이 자식 프로세스에게 상속된다는 말은 부모 프로세스의 핸들 테이블 정보가
자식 프로세스의 핸들 테이블에 복사된다는 뜻이다.
4. 가짜 핸들(Pseudo 핸들)
GetCurrentProcess 함수 호출을 통해 얻은 핸들을 가짜 핸들이라 하며,
핸들 테이블에 등록된 핸들값이 아닌, 자기 자신의 프로세스를
가리키기 위한 약속된 상수이다. 핸들 테이블에 등록된 핸들을 얻기 위해서는
DuplicateHandle() 함수를 사용해야 한다.
5. 파이프
이름없는 파이프와, 이름있는 파이프가 있으며, 이름없는 파이프의 경우 아주
유용하므로 잘 알아둬야 한다.
'Windows > System Programming' 카테고리의 다른 글
기본적인 파일 입출력 함수들 part 1 예제 (0) | 2011.08.12 |
---|---|
기본적인 파일 입출력 함수들 part 1 (0) | 2011.08.12 |
프로세스 정보를 얻는 예 (소스코드) (0) | 2011.08.12 |
핸들의 상속과 커널 오브젝트의 Usage Count (0) | 2011.08.12 |
핸들 테이블과 오브젝트 핸들의 상속 (0) | 2011.08.12 |