1. 커널 오브젝트에 대한 이해

Windows 운영체제는 프로세스, 쓰레드, 파일 등의 리소스들을 관리하는데, 이때 필요한 데이터들을 저장하는 메모리 블록을 커널 오브젝트라고 한다.

ms에서 제공하는 시스템 함수를 통해 커널 오브젝트를 간접적으로 조작할 수 있다. 그 예로, 오브젝트 핸들(커널 오브젝트에 할당된 숫자)을 인자로 받는 SetPriorityClass() 함수를 통해 프로세스의 우선 순위를 변경할 수 있다.

 

2. 커널 오브젝트와 핸들의 종속 관계

커널 오브젝트는 프로세스가 아닌 운영체제에 종속적이다. 따라서 커널 오브젝트는 운영체제에 의해 소멸 시점이 결정된다. 또, 여러 프로세스에 의해 접근이 가능하다.

핸들은 운영체제가 아닌 프로세스에 종속적이다.

 

3. 커널 오브젝트와 Usage Count

프로세스가 소멸된다고 해서 커널 오브젝트가 소멸된다고 단언할 수 없다. CloseHandle()는 핸들이 가리키는 리소스를 해제하고 커널 오브젝트를 소멸시키는 일을 하는 것이 아니라, 단지 핸들을 반환하며 Usage Count를 1 감소시킬 뿐이다. 자식 프로세스의 핸들은 자식 프로세스의 커널 오브젝트에 저장되므로, 만약 자식 프로세스를 소멸시킬 때 커널 오브젝트까지 소멸된다면 부모 프로세스는 종료 코드를 얻을 수 없다.

커널 오브젝트를 참조하는 대상의 개수가 0일 때 소멸시키는 것이 Windows가 정한 방식이다.

자식 프로세스를 생성하자마자 CloseHandle() 함수를 호출한다면 Usage Count를 1로 만들 수 있다.

바탕화면에 있는 아이콘을 더블 클릭 하여 프로세스를 생성할 경우, 생성된 프로세스의 Usage Count는 2이다. 바탕화면 역시 독립적으로 실행 중에 있는 프로세스이다.

 

1. 프로세스의 이해

프로세스란 메인 메모리로 이동하여 실행 중에 있는 프로그램이다.

프로세스는 Data/Stack/Heap/Code영역으로 이루어진 메모리 구조와 Register Set으로 구성되어 있다. 메모리 구조는 프로세스 개수만큼 생성된다. Register는 현재 실행 중인 프로그램을 위한 데이터들로 채워지며, CPU 내에 존재한다.

우리가 사용하는 Windows를 멀티 프로세스 운영체제라고 한다.

 

 

2.1 프로세스의 스케줄링

하나의 CPU가 여러 개의 프로세스를 번갈아 가며 실행한다. 프로세스의 CPU 할당 순서와 방법을 결정짓는 일을 스케줄링이라고 하며, 스케줄링 알고리즘을 통해 수행된다.

운영체제는 스케줄러를 통해 A 프로세스가 I/O 일을 할 동안 다른 프로세스가 실행되도록 스케줄링 한다. 결국 실행되어야 할 다수의 프로세스가 존재한다면 CPU에게 쉴 틈이 주어지지 않는 셈이다.

 

2.2 프로세스의 상태 변화

Ready, Running, Blocked - 프로세스가 생성되어 소멸되기까지의 상태 변화.

Ready 상태에 있는 프로세스는 CPU에 의해 실행되기를 희망하는 상태이다. 스케줄러에 의해 관리되며, 선택된 프로세스는 CPU에 의해 실행된다.

프로세스들은 우선순위가 있다. 실행 중이어도 우선순위가 높은 프로세스가 새로 생성되면 잠시 Ready 상태가 되며, 우선순위가 높은 프로세스의 종료 또는 양보를 기다린다.

Ready 상태는 스케줄러에 선택되면 바로 실행이 가능한 상태이고, Blocked 상태는 스케줄러에 의해 선택될 수 없는 상태이다.

i/o에 상당 시간을 소모하므로 둘 이상의 프로세스 실행을 통해 CPU의 활용도를 높여 성능 향상을 가져온다.

 

 

3. 컨텍스트 스위칭

실행 중인 프로세스의 변경 과정에서 발생되는 컨텍스트 스위칭은 시스템에 많은 부하를 준다. 현재 실행 중인 프로세스의 데이터가 담겨 있는 레지스터의 저장 및 복원이 빈번하게 일어나므로.

프로세스 A가 Running 상태에서 Ready 상태로 갈 때, 프로세스 A 관련 레지스터 정보는 메모리에 저장되고, Ready에서 Running이 된 프로세스 B의 관련 레지스터 정보는 CPU의 레지스터에 복원되는 것.

 

 

4. 프로세스의 생성

프로그램 실행 중에 또 하나의 프로세스 생성이 가능하다. Windows가 제공하는 CreateProcess 함수를 통해 프로세스 생성이 가능하다.

https://docs.microsoft.com/ko-kr/windows/win32/procthread/creating-processes

 

프로세스 만들기 - Win32 apps

CreateProcess 함수는 만들기 프로세스와 독립적으로 실행되는 새 프로세스를 만듭니다. 그러나 간단히 하기 위해 관계를 부모-자식 관계라고 합니다.

docs.microsoft.com

자식-부모 프로세스 관계가 형성된다.

 

 

 

 

1. 컴퓨터 구조의 접근 방법

CPU 디자인 과정에서 컨트롤 유닛이 해석할 명령어가 만들어진다.

 

1-1. 명령어 구조와 명령어 디자인

레지스터 길이를 16비트로 정하였으니 명령어 길이도 16비트로 구성한다.

CISC보다 RISC가 클럭 당 처리할 수 있는 명령어 개수가 더 많다. (Pipelining 기법)

 

 

2. LOAD & STORE 명령어 DESIGN

LOAD: 메인 메모리에 있는 데이터를 레지스터에 이동시킨다.

STORE: 레지스터에 있는 데이터를 메인 메모리로 이동시킨다.

 

3. Direct 모드와 Indirect 모드

하나의 명령어에 여러 정보를 담으면 표현 가능한 데이터 크기의 제한이 생긴다.

Direct 모드는 모든 메모리 영역에 접근이 불가능하다.

InDirect 모드는 메모리 접근 방법에 다양성을 부여한다. [] 기호로 주솟값을 감싸면 Indirect 모드 연산 의미.

 

 

1. WIN32 vs WIN64

한 번에 송/수신할 수 있는 데이터와 처리(Fetch)할 수 있는 크기가 각각 32bits, 64bits이다.

표현할 수 있는 주솟값의 범위가 다르다.

 

2. 프로그램 구현 관점에서의 WIN32, WIN64

LLP64 vs LP64.

리눅스는 LP64, 윈도우는 LLP64라는 데이터 표현 모델을 따른다.

 

64bits 시스템에서는 포인터가 지닌 주솟값을 4바이트 정수형으로 형 변환 하지 말자.

 

Polymorphic 자료형.

#if defined (_WIN64)
typedef __int64 LONG_PTR;
typedef unsigned __int64 ULONG_PTR;
#else
typedef long LONG_PTR;
typedef unsigned long ULONG_PTR;
#endif

이때 'PTR'는 포인터 선언을 뜻하는 게 아니라, 포인터 연산에서 활용하기 위해 정의된 자료형임을 뜻한다.

 

3. 오류 확인

GetLastError() 함수.

Windows 시스템 함수가 오류를 뱉었을 때 바로 이 함수를 사용하면 오류의 원인에 해당하는 에러 코드를 얻을 수 있다. 전역 공간에 저장되므로, 오류 발생 직후에 확인해야 한다.

 

4. System Programming Project Design

 

01. Windows에서의 UNICODE

문자셋의 종류, 특성: 미국 정의 표준이고 1바이트로 표현되는 아스키코드, 2바이트로 표현되는 유니코드가 있다.

SBCS: Single Byte Character Set, 문자를 표현하는 데 1바이트 사용

MBCS: Multi byte Character Set, 어떤 문자는 1바이트로 어떤 문자는 2바이트로 사용

WBCS: Wide Byte Character Set, 모든 문자를 2바이트로 처리

 

01-1. WBCS, 유니코드 기반의 프로그래밍

char -> wchar_t

"ABC" -> L"ABC"

strlen -> wcslen

널 문자도 2바이트로 처리된다.

MBCS 방식을 지원하기 위한 main 함수가 존재한다면, 유니코드 방식을 지원하기 위한 wmain이 존재한다. 그리고 이 두 가지 방식을 모두 지원하기 위해 _tmain이 존재한다. 프로그램 실행 시 전달되는 문자열을 MBCS/SBCS 각각 다른 기반으로 구성한다.

 

02. MBCS와 WBCS의 동시 지원

유지보수, 배포에 많은 불편함 -> 버그로 이어질 소지

 

02-1. Windows 스타일 자료형

#include <windows.h>

typedef char CHAR;

typedef wchar_t WCHAR;

#define CONST const

typedef CHAR* LPSTR;

typedef CONST CHAR* LPCSTR;

typedef WCHAR* LPWSTR;

typedef CONST WCHAR* LPCWSTR;

 

02-2. MBCS와 WBCS 동시 지원 매크로

#ifdef UNICODE

 typedef WCHAR TCHAR;

...

#else

 typedef CHAR TCHAR;

...

#endif

 

02-3. MBCS와 WBCS를 동시 지원하는 함수들

#ifdef _UNICODE

 #define _tprintf wprintf

#else

 #define _tprintf printf

#endif

 

 

01. 시스템 프로그래밍

윈도우즈 시스템 프로그래밍이란 윈도우즈 운영체제 기반의 컴퓨터에게 일을 시키기 위한 프로그램을 구현하는 것.

 

02. 컴퓨터 하드웨어의 구성

CPU, 메인 메모리, 입출력 버스

 

03. CPU

ALU - Arithmetic Logic Unit의 약자로, CPU 내부에 있는 연산 담당 블록.

컨트롤 유닛 - CPU가 처리할 명령어 해석.

레지스터 - 컨트롤 유닛이나 ALU가 필요로 하는 데이터 및 명령어들을 임시적으로 저장하기 위한 공간.

버스 인터페이스 - CPU 내외부 요소들이 I/O 버스를 통해 데이터를 주고받는데, 이 주고 받는 방식을 이해하고 있는 인터페이스 장치.

클럭 신호 - CPU는 동기화를 위해 클럭 펄스에 맞춰서 일을 한다.

 

04. 프로그램의 실행 과정

Stored Program Concept: 프로그램은 컴퓨터 내부에 저장되어서 순차적으로 실행된다.

프로그램의 실행 과정: 전처리기-컴파일-어셈블러-링커

 

05. 하드웨어 구성의 재접근

Stored Program Concept의 명령어 실행 단계는 Fetch, Decode, Excution이다. 메인 메모리에서 명령어를 CPU에 Fetch하고, 컨트롤 유닛으로 Decode 한 다음, ALU에서 연산을 Excute 한다.

 

 

 

 

 

+ Recent posts