Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

codingfarm

5. 프로세스의 생성과 소멸 본문

Windows/윈도우즈 시스템 프로그래밍

5. 프로세스의 생성과 소멸

scarecrow1992 2020. 6. 15. 14:02

1. 프로세스(Process)의 이해

프로세스란 무엇인가?

$\bullet$ 정의 : 실행중에 있는 프로그램

$\bullet$ 프로세스의 범위 : 메모리 구조 + 레지스터 set

프로그램 프로세스
하드디스크에 저장된 실행될 수 있는 파일 메모리에 올라가서 실행되고 있는 프로그램

 

프로세스를 구성하는 요소

1) 프로그램 실행시 메모리 구조

프로세스 하나마다 위와같은 분리된 메모리 공간이 형성된다.

각 프로세스는 서로의 메모리 영역에 접근이 불가능하다.

 

Register Set

$\bullet$ CPU가 특정 프로그램을 실행중이라면 CPU내부 레지스테들은 프로그램 실행을 위한 데이터들로 채워지게 된다.

$\bullet$ 레지스터의 상태도 프로세스의 일부로 포함시켜야 한다.

-이는 Context Switching에서 매우 중요한 요소이다.

-이미 running 상태에 있는 process를 ready상태로 바꿀때 register에 있는 process의 data를 메모리에 임시 저장하고 비어있는 register에는 새로운 process의 data로 채워진다.

 

 

2. 프로세스의 스케줄링 상태 변화

프로세스의 스케줄링(scheduling)

$\bullet$ 하나의 CPU가 여러개의 프로세스를 번갈아가며 실행시킬때 CPU할당시간을 나누는 것이다.

$\bullet$ 스케줄러는 Runing과 Ready 상태간의 변화를 관리한다.

(Blocked 상태는 스케줄러의 권한 밖이다.)

 

1) 스케줄링 : 프로세스의 CPU 할당 순서 및방법을 결정짓는 일

2) 스케줄러 : 스케줄링 알고리즘을 이용하여 실제 프로세스를 관리하는 운영체제 요소

3) 스케줄링 알고리즘 : 스케줄링시에 적용되는 알고리즘

 

프로세스의 상태변화

$\bullet$ 프로그램 실행과정에서 대부분의 시간은 I/O에 할당된다.

-I/O는 파일 입출력, 네트워크를 통한 송수신 등이 있다.

$\bullet$ I/O에 관련된 일에는 CPU가 관여하지 않는다.

$\bullet$ I/O에 관련된 일을 하는동안 CPU는 그 프로세스가 아닌 다른 프로세스를 스케줄러를 통해 실행한다.

상황 1 : Start $\rightarrow$ Ready

$\bullet$ S는 프로세스의 생성을 의미한다.

$\bullet$ 프로세스는 생성과 동시에 Ready 상태로 들어간다.(이미 실행중인 프로세스가 있을 것이므로)

 

상황 2 : Ready $\rightarrow$ Running

$\bullet$ Ready 상태의 프로세스들은 스케줄러에 의해 관리되는 프로세스들이다.

$\bullet$ 스케줄러는 Ready 상태의 프로세스 중 하나를 택하여 CPU에 의해 실행될 수 있게 한다.

 

상황 3 : Running $\rightarrow$ Ready

$\bullet$ 우선순위(priority)가 보다 높은 프로세스를 위해 Running 상태의 Process를 잠시 멈추고 우선순위가 높은 프로세스를 실행시킨다.

$\bullet$ 이때 실행을 멈춘 프로세스는 Ready상태가 된다.

 

상황 4 : Running $\rightarrow$ Blocked

$\bullet$ 실행 중인 프로세스가 실행을 멈추는 상태로 들어가는것

$\bullet$ 데이터 입출력에 관련된 일을 하는 경우에 발생한다.

$\bullet$ I/O는 CPU의 관할 밖이다.

즉, 실행중인 process가 I/O를 해야하는 상황이 오면 Blocked 상태가 되고 Ready상태의 프로스세가 Running 상태로 된다.

 

상황 5: Blocked $\rightarrow$ Ready

$\bullet$ 입출력이 완료된 프로세스가 다시 Ready상태로 되는 과정이다.

$\bullet$ Blocked 상태는 동시에 여러개가 될 수 있다.

 

 

3. 컨텍스트 스위칭(Context Switching)

$\bullet$ 정의 : 이미 실행중인 프로세스보다 더 높은 우선순위의 프로세스 만날시에 Ready, Running 상태가 바뀌게 되는데 이미 실행중이던 레지스터들은 메모리에 저장된다.(나중에 다시 실행을 이어나가기 위해 데이터를 보존해야한다)

$\bullet$ Context Switching은 멀티 프로세스 기반의 프로그램 실행의 단점이다.

-컨텍스트 스위치은 시스템에 많은 부담을 준다.

 

 

4. 프로세스의 생성

프로세스의 생성

$\bullet$ 실행중인 프로세스가 또다른 프로세스를 생성하는 것이다.

$\bullet$ 현재 프로세스로 해결할 수 없는 상황에 직면시 또다른 프로세스를 생성한다.

 

CreateProcess 함수의 이해

$\bullet$ 부모 프로세스(Parent Process) : CreateProcess 함수를 호출한 프로세스

$\bullet$ 자식 프로세스(Child Process) : CreateProcess 함수에 의해 생성되는 프로세스

If the function fails, the return value is zero.

 

BOOL CreateProcess(

1) LPCTSTR spApplicationName

$\bullet$ 생성할 프로세스의 실행파일 이름을 인자로 전달한다.

$\bullet$ 경로명을 추가로 전달 할 수 있다.

-비지정시에 현재 디렉터리(current directory)에서 실행파일을 찾게된다.

-파일명을 못찾을 경우 함수 호출에 실패한다.

 

2) LPTSTR lpCommandLine

$\bullet$ 새로 생성하는 프로세스에 인자 전달시 사용한다.(main에 전달한다.)

$\bullet$ 1)에 NULL을 전달하고 2)에 실행파일 이름을 더불어 전달 할 수 있다.(표준 검색 경로로 찾게된다.)

$\bullet$ 전달인자의 문자열은 상수가 아닌 변수여야 한다. (함수가 내부적으로 2번 매개변수를 변경후에 다시 원래대로 되돌린다.)

 

3) CPSECURIY_ATTRIBUTES lpProcessAttributes

$\bullet$ 프로세스의 보안속성을 지정할 때 사용하는 인자

$\bullet$ 보통 NULL을 전달 (Default 보안 속성이 지정된다.)

이 매개변수는 주로 생성하는 프로세스의 핸들 자체의 상속성 여부를 결정한다.(추후 자세히 배운다.)

 

4) LPSECURITY_ATTRBUTES lpThreadAttributes

$\bullet$ 쓰레드의 보안속성을 지정할 때 사용하는 인자

$\bullet$ 보통 NULL을 전달 (Default 보안 속성이 지정된다.)

 

5) BOOL bInheritHandle

$\bullet$ 부모프로세스가 소유하는 핸들 중 일부(handle table)의 상속여부를 결정한다

$\bullet$ TRUE : 상속을 허가한다.

$\bullet$ FALSE : 상속을 거부한다.

부모 프로세스가 소유한 핸들 테이블 자체를 생성될 자식 프로세스로 상속성을 결정한다.

 

 

6) DWORD dwCreationFlag

$\bullet$ 생성하는 프로세스의 특성을 결정짓는다.(우선순위)

$\bullet$ 설정할 필요가 없을시에 0을 전달한다

CREATE_NEW_CONSOLE 새로운 창의 프로세스를 만든다
0 현재 부모 콘솔 창에 프로세스를 공유한다.

 

7) LPVOID lpEnvinronment

$\bullet$ 자식 프로세스가 부모푸로세스의 Envinronment Block에 저장된 문자열의 상속성 여부를 결정짓는다.

$\bullet$ Envinronment Block

-프로세스마다 소유하고 있는 메모리 블록

-프로세스가 실행에 필요로 하는 문자열을 저장한다.

$\bullet$ NULL : 환경블록에 저장된 문자열을 상속한다.

 

8) LPCTSTR lpCurrentDirectory

$\bullet$ 생성하는 프로세스의 현재 디렉터리를 설정하는 인자이다.

$\bullet$ NULL : 부모 프로세스의 현재 디렉터리가 자식 프로세스의 현재 디렉터리가 된다.

 

9) LPSTARTUPINFO lpStartupInfo

$\bullet$ STARTUPINFO 구조체 변수를 초기화 한 다음에 이 변수의 포인터를 인자로 전달한다.

$\bullet$ 생성하는 프로세스의 속성을 지정할 때 사용된다.

 

10) LPPROCESS_INFORMATION lpProcessInformation

$\bullet$ 생성하는 프로세스의 정보를 얻기위한 인자이다.

$\bullet$ PROCESS_INFORMATION 구조체 변수의 주소값을 인자로 전달한다.

$\bullet$ 주소가 전달된 변수에 생성된 프로세스의 정보가 채워진다.

9)를 통해 자식 프로세스 생성을 위한 정보를 전달하고 10)을 통해 생성이후의 정보를 부모프로세스가 얻는다.

 

CreateProcess 함수 이해하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
typedef struct _STARTUPINFOW {
    DWORD   cb;                    //구조체 변수의 크기
    LPWSTR  lpReserved;
    LPWSTR  lpDesktop;
    LPWSTR  lpTitle;            //콘솔 윈도우의 타이틀 바 제목
    DWORD   dwX;                //프로세스 윈도우의 x,y 좌표
    DWORD   dwY;
    DWORD   dwXSize;            //프로세스 ㄴ도우의 가로,세로 크기
    DWORD   dwYSize;
    DWORD   dwXCountChars;
    DWORD   dwYCountChars;
    DWORD   dwFillAttribute;
    DWORD   dwFlags;            //설정된 멤버의 
    WORD    wShowWindow;
    WORD    cbReserved2;
    LPBYTE  lpReserved2;
    HANDLE  hStdInput;
    HANDLE  hStdOutput;
    HANDLE  hStdError;
} STARTUPINFOW, *LPSTARTUPINFOW;
#ifdef UNICODE
typedef STARTUPINFOW STARTUPINFO;
typedef LPSTARTUPINFOW LPSTARTUPINFO;
#else
typedef STARTUPINFOA STARTUPINFO;
typedef LPSTARTUPINFOA LPSTARTUPINFO;
#endif // UNICODE
cs

이제 CreateProcess 함수의 사용법을 익혀보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// AdderProcess.cpp
 
#include<stdio.h>
#include<tchar.h>
#include<windows.h>
 
int _tmain(int argc, TCHAR* argv[]) {
    DWORD val1, val2;
    val1 = _ttoi(argv[1]);
    val2 = _ttoi(argv[2]);
 
    _tprintf(_T("%d + %d = %d \n"), val1, val2, val1 + val2);
    _gettchar();    //프로그램의 실행을 잠시 멈춘다.
    return 0;
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// CreateProcess.cpp
 
#include<stdio.h>
#include<tchar.h>
#include<windows.h>
 
#define DIR_LEN MAX_PATH + 1
 
int _tmain(int argc, TCHAR* argv[]) {
    STARTUPINFO si = { 0, };
    PROCESS_INFORMATION pi;
 
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USEPOSITION | STARTF_USESIZE;
    si.dwX = 100;
    si.dwY = 200;
    si.dwXSize = 300;
    si.dwYSize = 200;
    TCHAR title[] = _T("I am a boy!");
    si.lpTitle = title;
    TCHAR command[] = _T("AdderProcess.exe 10 20");
    TCHAR cDir[DIR_LEN];
    BOOL state;
 
    GetCurrentDirectory(DIR_LEN, cDir);
    _fputts(cDir, stdout);
    _fputts(_T("\n"), stdout);
 
    //SetCurrentDirectory(_T("C:\\WinSystem"));//이 디렉터리 안에 AdderProcess가 있어야 한다.
    GetCurrentDirectory(DIR_LEN, cDir);
    _fputts(cDir, stdout);
    _fputts(_T("\n"), stdout);
 
    state = CreateProcess(
        NULL,
        command,
        NULLNULL, TRUE,
        CREATE_NEW_CONSOLE,
        NULLNULL&si, &pi
    );
 
    if (state != 0)
        _fputts(_T("Creation OK! \n"), stdout);
    else
        _fputts(_T("Creation Error! \n"), stdout);
 
    return 0;
}
cs

CreateProcess.cpp 의 실행결과는 아래와 같다.

 

검생경로

CreateProcess의 두번째 전달인잘르 통해서 실행파일 이름을 전달할 경우, 아래 와 같은 표준 검색경로 순서대로 실행파일을 찾는다.

1) 실행중인 프로세스의 실행파일이 존재하는 디렉터리

2) 실행중인 프로세스의 현재 디렉터리(Current Directory)

3) Windows의 시스템 디렉터리(System Directory)

4) Windows 디렉터리(Windows Directory)

5) 환경변수 PATH에 의해 지정되어 있는 디렉터리

 

GetCurrentDirectory

GetSystemDirectory

GetWindowsDirectory

 

프로세스의 생성 단계

1)STARTUPINFO 구조체 변수의 생성 및 초기화

2) 현재 디렉터리의 설정(SetCurentDirectory) - 안해도 무방

3) CreateProcess 함수 호출

 


  1. 프로세스에 대한 이해
    • 프로세스란 무엇인가?
    • 멀티 프로세스 OS란 무엇인가?
  2. 프로세스의 상태
    • 프로세스가 생성되어 소멸되기 까지 겪는 상태의 변화를 서술하라
    • ready, running, blocked 상태가 되기 위한 조건과 각 상태에 대해 서술하라
  3. 컨텍스트 스위칭
    • 컨텍스트 스위칭에 대해 서술하라
    • 컨텍스트 스위칭이 발생하는 과정에 대해 서술하라
      • 현재 실행중인 프로세스 레지스터 정보를 메모리에 저장, 실행하고자 하는 프로세스의 정보를 레지스터에 복원 후 CPU에서 실행
    • 컨텍스트 스위칭이 시스템에 부하를 주는 이유
  4. 프로세스를 생성하는 방법
    • CreateProcess 함수의 사용법에 대해 서술하라
  5. 프로세스의 메모리 구조
    • 프로세스의 메모리 구조에 대해 설명하라
    • 왜 프로세스는 독립된 메모리 구조를 지니는가?
      • 신뢰성과 안정성을 높이기 위해

 

 

 

 

 

 

Comments