본문 바로가기
IT창고/System

프로세스가 죽으면 다시 살림

by 창구창고 2007. 1. 22.
반응형
/*
1. EProcess 의 포인터가 Process Enviroment Block을 가리키고 있다.
   PEB(Process Enviroment Block)에는 현재 디렉토리, 환경변수,command line argument을 가지고 있다.
2. Eprocess에는 프로세스 ID를 가지고 있다.
*/
#include<stdio.h>
#include<windows.h>
/*
void main()
{
	//현재 프로세스의 ID얻기 -> EPROCESS 에서 꺼내오는 함수.
	DWORD pid =  GetCurrentProcessId();
	printf("프로세스 ID : %d\n",pid);

	//현재 디렉토리 얻기,
	char dir[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, dir);
	printf("현재 디렉토리 : %s\n",dir);
	//command line argument 얻기
	char *p = GetCommandLine();
	printf("Command Line Argument : %s\n\n", p);

	//환경 변수 꺼내기 
	char temp[1024];
	GetEnvironmentVariable("PATH",temp, 1024);
	printf("PATH라는 환경 변수 : %s\n",temp);
}
*/
/*3. entry
mainCRTStartup()이 먼저 실행후 main()이 실행된다. <~ 모든 C언어에서 그렇다.
하지만 제일 먼저 실행되는 것은 Start of Process 라고 불리는 함수가 있다.(정식명칭은 아니다. MS가 오픈을 안했으므로)
OS - call -> Start of Process - call ->mainCRTStartup() - call ->main()
Start of Process는 커널32.dll에 있다. <~ 항상 같은 주소에 있다.

4. 프로세스 생성
	1. WinExec()
	2. CreateProcess()
	WinExec()가 CreateProcess()를 부른다.
	C에선 system()으로 다른 프로세스를 실행 시켰다.
//TerminateProcess는 비동기 함수
			//비동기함수 : 함수가 완전히 종료되지 않고 중간에 돌아오는 시점에 해당하는 함수가 
			//				종료 되었느지 확신할 수 없다. -> 확인해야한다.
			//PKO는 살아있을때 nonsinal 죽었을때 signal

			//Wait for SingleIbject) <~ 매우중요
*/
/*
1. 자식의 핸들을 닫는다.- 그 이유
2. 종료 코드
	Eproces 안에는 종료 코드가 있다. 프로그램이 실행중일경우는 STILL_ACTIVE로 있다가 종료 되었을때 main()함수의 리턴값을 받는다.

*/
/*
void main()
{
	//표준 C함수 사용
	//system("freecell.exe");//프리셀에 떠있는동안은 다음줄이 실행이 안된다.

	WinExec("freecell.exe",SW_SHOW); //다른프로그램이 실행되어도 다음 코드가 실행된다.
	printf("Bye~~\n");
}
*/
void main()
{
	PROCESS_INFORMATION pi	=	{ 0 };
	STARTUPINFO si	=	{ 0 };
	si.cb	=	sizeof(si);
	BOOL b = CreateProcess("C:\\WINDOWS\\system32\\freecell.exe",				//APP이름		< ~ 절대 경로를 줘야 한다.
						   0,//"freecell.exe",	//APP이름 + command line args	<~ 그냥 써도 된다.
						   0,0,				//PKO,TKO 보안
						   //PKO 보안을 설정하면 작업관리자에서 죽일수 없는 프로그램을 만들수 있다.
						   FALSE,			// KOHT의 상속여부->부모의 테이블 상속여부
						   NORMAL_PRIORITY_CLASS,//우선순위 | 플래그
						   0,0,				//환경변수 , 현재 디렉토리
						   &si,				//startup info정보
						   &pi);			//생성된 프로세스,스레듸 핸들과 ID를 담을 변수
											
											
	if(b)
	{
		//자식의; 핸들을 닫는 이유를 반드시 알아야 한다.
		//자식의 핸들을 닫지 않으면 자식이 종료 되어도 자식을 관라하던 
		//PKO,TKO는 파괴 되지 않고 있다가 (참조개수 1)부모가 자식의핸들을 
		//닫거나 부모가 종료(자동으로 핸들 닫힘)되어야 PKO,TKO 파괴된다.

//		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
	}

//	int cmd;

	while(1)
	{
		//scanf("%d",&cmd);

		//if(cmd == 2)
		//{
			//프로세스 가제로 종료하기
			//자식프로세스를 강제로 죽이면 종료코드를 메인의 끝까지 갈 수 없다.
			//그래서 종료 코드를 100으로 넣고 종료한다.
			//TerminateProcess(pi.hProcess,100);	//100은 종료 코드
			//TerminateProcess는 비동기 함수이다. 즉 .. 이순간 
			//정말로 죽었다고 생각할 수는 없다.

			//모든 프로세스는 죽을때 PKO가 Signal된다.
			//특정 KO가 시그널 될때까지 현재 실행흐름(스레드)를 대기 시킨다.


			//이제 정말로 자식 프로세스는 죽었다.
			
		//	cmd =1;
		//}
		
	//	if(cmd == 1)
	//	{
			DWORD code;
			GetExitCodeProcess(pi.hProcess, &code);//프로세스의 종료 코드얻기

			if(WaitForSingleObject(pi.hProcess,INFINITE))//code == STILL_ACTIVE )//0x103으로 정의된 상수
			{
				//printf("아직 자식이 살아 있습니다.\n");
				break;
			}
			else 
			{
				printf("자식 종료 : %d\n",code);
				CloseHandle(pi.hProcess);
				b = CreateProcess("C:\\WINDOWS\\system32\\freecell.exe",				//APP이름		< ~ 절대 경로를 줘야 한다.
						   0,//"freecell.exe",	//APP이름 + command line args	<~ 그냥 써도 된다.
						   0,0,				//PKO,TKO 보안
						   //PKO 보안을 설정하면 작업관리자에서 죽일수 없는 프로그램을 만들수 있다.
						   FALSE,			// KOHT의 상속여부->부모의 테이블 상속여부
						   NORMAL_PRIORITY_CLASS,//우선순위 | 플래그
						   0,0,				//환경변수 , 현재 디렉토리
						   &si,				//startup info정보
						   &pi);			//생성된 프로세스,스레듸 핸들과 ID를 담을 변수
											
	
			}
//		}
	}
}
반응형

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."