관리 메뉴

KorSA

구조를 알아야 개발이 보인다 (C++로 풀어보는 윈도우 구조) 본문

Books/Software Developments

구조를 알아야 개발이 보인다 (C++로 풀어보는 윈도우 구조)

Praiv. 2020. 12. 21. 23:20
320x100

이 글은 비제이퍼블릭에서 출간한 "(C++로 풀어보는 윈도우 구조) 구조를 알아야 개발이 보인다" 책을 읽고 나서 일부를 발췌한 내용입니다.

 

[ 1장 - 왜 개발자는 윈도우를 알아야 하는가 ]

p4) 프로그램을 개발하면 매번 문재 해결의 난관에 부딪치게 됩니다. 여기에서 문제를 해결할 수 있는 포인트를 하나 더 안다는 것은 엄청난 실력 차이를 가질 수 있게 되는 것입니다.

 

p9) 윈도우는 NT 4.0(윈도우 95, 98, ME) 에서 많이 바뀌게 되었습니다. 현재 윈도우 10의 시스템 아키텍처 역시 대부분 NT 4.0의 구조에서 큰 줄기는 바뀌지 않았을 정도입니다. 

 

p14) Windows Sysinternals 프로그램 : 프로세스나 스레드, 메모리가 윈도우에서 어떻게 동작하는지 확인할 수 있도록 도와주는 도구

 

 

[ 2장 - 윈도우 기본 개념 이해하기 ]

p53) 윈도우 기본 요소: 유저 모드와 커널 모드, 프로세스, 스레드, 가상 메모리, 객체와 핸들, 멀티프로세싱, 유니코드, 서브시스템, 세션

 

p57) Ring 0는 최고 권한으로 커널 모드라 합니다. Ring 0는 시스템 자원을 통제 없이 마음대로 사용할 수 있지요. 유저 모드에는 Ring 3 권한을 주어, 하드웨어를 이용하기 위해 권한을 요청해서 올바른 요청인지 확인한 수에 사용이 가능합니다. (유닉스 시스템에서도 동일한 방식으로 권한을 구분합니다.)

 

p62) 프로세스 익스플로러: Sysinternals 사에서 제공하는 프로세스 분석 도구

 

p67) 윈도우에서 프로그램을 실행하는 데 필요한 정보의 구조를 PE(Portable Executable)라고 부릅니다.

 

p68) 스레드는 프로그램의 실행 코드를 커널에서 처리하는 역할을 담당합니다.

 

p72) 가상 메모리는 물리 메모리와 디스크를 이용한 메모리를 모두 통합하여 관리해서 프로세스들이 메모리를 의식하지 않고 사용할 수 있도록 도와주는 역할을 담당합니다.

 

p74) 메모리 분석을 도와주는 도구로 VMMap이 있습니다.

 

p81) 프로세스 익스플로러의 Handle 열 정보에서 Object Address 정보는 유용합니다. Object Address가 바로 객체가 실제로 저장된 메모리 주소입니다.

 

p85) 윈도우는 다수의 프로세서가 하나의 메모리 영역과 하드웨어 자원들을 공유해서 사용하는 대칭형 다중 처리(Symmetric multiprocessing, SMP)를 지원합니다. 현재 리누긋와 같은 대부분의 시스템들이 지원하는 시스템 구조가 보로 SMP입니다.

 

p86) 여러분이 개발을 할 때도 다수의 스레드를 사용하는 프로그램을 만든다면, 논리 프로세서가 많은 하드웨어에서 더 빠른 성능을 발휘할 것입니다. 단, 주의할 점이 있는데 윈도우는 제품별로 지원하는 프로세서 개수를 제한하고 있으므로, 윈도우 버전을 선택할 때에도 지원하는 프로세서 개수를 함께 고려해야 한다는 것입니다.

 

p87) 서버 제품은 보통 서비스를 제공하는 용도로 사용하다 보니, 많은 요청이 발생하는 서버의 경우 요청에 따라 스레드가 많이 생성될 수 있습니다. 스레드 기준으로 프로세서들이 할당받아 처리하기 때문에 논리 프로세서가 많을수록 작업도 빨리 처리할 수 있게 되지요. 서버는 동시에 작업을 수행하기 때문에 용도에 맞도록 물리적 프로세서를 많이 지원합니다. 클라이언트 제품군인 윈도우 10과 같은 제품은 개인이 사용하기 알맞게 그에 보편적으로 많은 물리적 프로세서를 지원할 필요가 없도록 설계되어 제작된 제품입니다.

 

p104) 환경 서브시스템은 응용 프로그램의 실행을 위한 환경 부분과 프로세스 관리만 담당합니다. 처음 프로세스를 실행하게 되면, 바로 환경 서브시스템이 프로세스의 자원들을 받아서 메모리에 로드하고 실행할 준비를 한 다음 초기 스레드(메인함수)를 실행해주는 역할을 하는 것입니다.

 

p105) 주요 서브시스템 DLL

1) Kernel32.dll: 파일 생성과 같은 하드웨어 요청에 주로 사용됩니다.

2) Advapi32.dll: 보안 구성이나 확인 등 추가적으로 윈도우에서 제공하는 기능적인 부분들에 사용됩니다.

 

p107) 서브시스템을 화면으로 관찰하기 쉽게 구현한 프로그램이 바로 Dependency Walker입니다.

 

p109) NTDLL(Ntdll.dll) : 서브시스템 바로 하단에서 동작하며, 유저 모드에서 동작 중이던 프로그램들을 위해 커널 모드의 요청을 대신 처리한 후 결과 값을 반환해주는 역할을 합니다.

 

p110) Kernel32.dll을 프로그램들이 이용하는 이유는 유저 모드의 특성에서 얘기했던 것처럼 유저 모드에서는 오류로 다시 실행해도 큰 문제가 없지만, 커널 모드에서 오류가 발생하게 되면 바로 시스템 중지로 이어지기 때문에 2중 보안 장치를 구성한 것이라고 할 수 있습니다.

 

p115) 환경 서브시스템은 프로그램이 현재 실행되고 있는 영역을 관리해주는 역할입니다. (서브시스템 DLL과는 전혀 다름)

 

p118) 세션은 윈도우에서 다중 사용자 혹은 화면을 제어하기 프로그램을 개발할 때 먼저 이해해야 하는 영역입니다. 세션은 프로그램을 실행시킨 사용자만이 해당 프로그램의 입력과 출력을 보장받고 제어할 수 있도록 구분해주는 역할을 합니다. 그리고 세션에는 2개의 구성 요소들이 존재하는데 바로 Window Station과 Desktop입니다. 하나의 세션은 하나 혹은 여러 개의 Window Station으로 구성되고, 하나의 Window Station은 하나 혹은 여러 개의 Desktop으로 구성됩니다.

 

p122) WinSta0는 사용자의 입력 및 화면 출력과 같은 화면과 상호작용할 수 있는 세션 내에서 유일한 Window Station 입니다. 그 외의 Window Station들은 사용자의 입력을 받는다거나 화면을 제공할 수 없는 Window Statione들인 것입니다. 즉 서비스들이 실행되는 세션은 사용자의 입력을 받을 수 없고 화면을 제공할 필요도 없기 떄문에 WinSta0를 사용하지 않습니다.

 

p122) WinSta0는 사용자 입력 및 화면 출력이 가능한 공간으로, 기본적으로 로그인(Login) Desktop과 기본 사용자 바탕화면(Default) Desktop 그리고 스크린 세이버 (Screen Saver) Desktop 3개를 생성합니다.

 

p125) Visual Studio의 Tool 메뉴에 존재하는 Error Lookup 도구를 사용해서 GetLastError()로 얻은 오류 코드의 의미를 간단하게 알 수 있습니다.

 

p133) Desktop은 모니터를 두 개 연결하여 확장된 바탕화면이 아니라 완전히 별도의 작업 공간을 제공하는 것을 의미합니다. 기본적으로 생성되는 3개의 Desktop도 동일한 Window Station을 사용하지만 서로 분리된 화면으로 판단하시면 됩니다. 즉 우리가 로그인을 하게 되면 현재 화면에서 로그인 화면이 없어지는 것이 아니고 Desktop이 변경됩니다.

 

p142) 윈도우 10부터 제공되는 Virtual Desktop은 환경 서브시스템의 Desktop과는 다른 개념입니다. 구조적으로 보면 Desktop 하위에 다시 Virtual Desktop으로 나누어 관리하는 것입니다.

 

 

[ 3장 - 프로세스 ]

p162) LPWSTR의 의미: LP는 Long Pointer의 약자로, 포인터로 판단하시면 됩니다. Long Pointer라고 표현한 이유는 10년전 16비트 컴퓨터가 주류일 때 사용하던 16비트 Pointer와 구별하기 위함입니다. W는 와이드형 문자열, 유니코드라는 얘기입니다. STR은 문자열을 의미합니다.

 

p173) 신규 Desktop에 프로세스를 생성하려면 STARTUPINFO 구조체를 이해해야 합니다.

 

 

[ 4장 - 스레드 ]

p215) 스레드 우선순위에서 숫자가 높을수록 빠른 처리가 필요한 스레드를 의미합니다. 그리고 가장 낮은 우선순위인 0은 스레드 대신 Zeropage Thread라는 프로세스가 사용하여, 프로세스에서 더 이상 사용하지 않는 메모리를 해제하는 작업에 이용됩니다.

 

p231) 높은 사용 권한(UAC, User Account Control) : 관리자와 같이 컴퓨터의 중요한 기능을 사용할 수 있는 권한을 말합니다. 비스타 이후 추가된 보안 기술로서, 응용 프로그램들이 실행될 때 컴퓨터를 사용하는 관리자가 권한 수준을 높이는 것을 허용하기 전에는 표준 사용자 권한으로 실행하도록 하여 시스템의 중요한 변경을 하지 못하도록 하는 보안 기술입니다. 관리자 권한을 가진 사용자가 사용하는 환경이더라도 응용 프로그램은 사용자에게 승인을 받아야만 높은 권한을 사용할 수 있습니다.

 

p236) CPU Stress라는 도구를 이용하여 Context Switches/sec 등의 수치를 확인할 수 있습니다.

 

p264) 멀티스레드와 같지만 조금 다른 개념으로 병렬 처리가 있습니다. 요즘 대다수의 컴퓨터는 멀티 프로세서를 사용하고 있습니다. 따라서 다중 처리를 지원하며, 필요한 경우 동시에 프로세서 수만큼 코드를 처리할 수 있습니다. 예를 들어 for문을 여러 프로세서에서 작업하고 순차적으로 계산한 것과 동일한 결과물을 내는 일에 활요할 수 있습니다. 마이크로스프트는 생산성을 보다 높이기 위해서 C++ 11과 .NET 4버전부터 병렬 처리 라이브러리를 제공하여 기존에 fork/join을 직접 사용하지 않고, 마이크로소프트에서 제공하는 Parallel Patterns Library(PPL)를 이용하면 기존보다 쉽게 병렬 프로그래밍을 구현해 보다 빠른 처리를 할 수 있도록 했습니다.

 

p268) 병렬 처리는 멀티 프로세서의 성능을 최대한 사용할 수 있는 유용한 함수입니다.

 

 

[ 5장 - 객체와 핸들 ]

p272) 객체 관리자는 프로세스 관리자, 메모리 관리자와 같은 커널의 주요 관리자 중 하나입니다. 또한 객체 관리자는 커널 실행부 영역의 한 부분으로서, 객체를 생성하거나 삭제하고 현재 객체를 이용하는 핸들 수를 확인하는 등의 관리 역할을 수행합니다.

 

p302) 핸들 권한은 작은 부분이지만, 윈도우 시스템은 권한을 기반으로 하는 시스템이기 때문에 시스템 프로그래밍을 한다면 현재 충분한 권한이 있는지, 과도하게 권한을 사용하고 있지 않은지를 확인하는 습관을 기르는 것이 중요합니다.

 

 

[ 6장 - 메모리 ]

p320) 페이징 파일과 커밋 크기에 대해 테스트를 하고자 한다면 직접 스택이나 힙을 만들어서 테스트해볼 수도 있지만, Sysinternals에서 제공하는 Testlimit 도구를 통해서도 간단히 테스트해볼 수 있습니다.

 

p321) 페이지 공유는 윈도우 시스템에서 제공하는 DLL을 동일한 주소에서 로드할 수 있게 해줍니다. 만약 30개의 프로세스가 실행되고 있다면, 동일한 DLL을 사용하는 것만으로도 많은 메모리를 절약할 수 있습니다.

 

p329) 우리가 프로그램을 실행하면 윈도우는 프로세스를 생성하면서 기본적으로 1개의 힙을 생성합니다. 이를 기본 프로세스 힙이라고 합니다. 기본 프로세스 힙 이외에 개발자가 직접 할당한 힙은 사용이 끝났거나 프로그램 종료 시 힙을 직접 해제해주어야 합니다.

 

p330) 만약 힙을 잘 관리하지 못한 경우 프로그램을 종료해도 힙은 계속 메모리에 남아 있어 메모리 누수가 일어나게 되고, 시스템에서 중요한 자원인 메모리가 낭비되어 프로그램의 오류나 시스템이 불안정하게 됩니다.

 

p337) 프론트엔드 할당자의 가장 큰 특징은 단방향 연결 리스트를 이용한다는 것입니다. 그리고 프론트엔드 할당자는 같은 크기의 메모리를 반복적으로 할당 및 해제할 경우 이용하는데, 물리 메모리 영역에 위치하고 있어 매우 빠르게 동작합니다. 프론트엔드 할당자 안에는 비스타 이전 버전에서 사용된 Lookaside list와 저단편화 힙(Low fragmentation heap, LFH)을 가지고 있습니다. 그리고 비스타 이상 버전에서는 저단편화 힙을 기본적으로 사용하도록 설정되어 있습니다.

728x90
728x90
Comments