Transcript Memory
과목 : 윈도우즈 프로그램밍 특론
메모리와 스레드
발표자 : 권만준
지능자동화연구실/충북대학교
2004년 05월 04일 화요일
발표순서
메모리 관리
-
가상 메모리(Virual Memory) 개념 및 관련 함수
GlobalAlloc와 LocalAlloc 함수
Heap에 메모리 사용 함수
배열에 메모리 할당 new
메모리 공유 기법
스레드
- 스레드 구동 방법
- 뮤텍스(Mutex), 세머포어(Semaphore), 이벤트
(Event)
- 멀티 스레드 예제
윈도우즈 프로그래밍 특론
메모리와 스레드
가상메모리(Virtual Memory)
~ 메인 메모리와 함께 보조 기억 장치, 즉 보통 하드(HDD)라고
하는 곳의 일부분을 메모리로 사용하는 것.
가상 메모리 관리자(VMM, Virtual Memory Manager)
응용 프로그램이 사용하는 가상 메모리(Virtual Memory)
를 실제 메모리(Physical Memory)로 변환해주는 역할
을 담당
Win32에서 각 응용 프로그램은 모두 4GB의 주소 공간
을 할당 - 2GB의 메모리 공간을 사용할 수 있음
가상 메모리는 4KB(페이지) 씩으로 나뉘어 관리
- 실제 메모리는 크게 두 부분으로 구성된다. RAM과
스왑 파일(swap file)이라고도 하는 하드디스크 내의
페이징 파일로 구성
윈도우즈 프로그래밍 특론
메모리와 스레드
메모리 구조
윈도우98 메모리 구조
4GB
Linear Address
3GB
2GB
4M
B
Page Tables
VxDs
VMM
System arena
(Ring 0 shared)
System DLLs
Memory-mapped Files
Upper portion of Win16 global heap
Shared arena
(Ring 3 shared)
Win32 code, data and resources
(distinct linear to physical
mapping for end process)
Lower portion of Win16 global heap
MS-DOS
Private arena
(per process
area)
DOS area
0
윈도우즈 프로그래밍 특론
메모리와 스레드
가상 메모리 페이지 형태
사용(Committed) 페이지
실제 메모리에 할당된 페이지. 이 페이지만이 접근 가능.
접근 제어 모드 - 접근 불가(No Access), 읽기 전용(Read
Only), 읽기/쓰기 모드
예약(Reserved) 페이지
프로그램에 의해 할당은 되었지만 아직 쓰이지는 않고 있는
페이지
이 영역을 사용하려고 하면 페이지 폴트(page fault)가 일어
나고, 그 페이지를 사용 페이지로 변환
자유(Free) 페이지
예약 페이지가 된 후 사용 페이지로 변환
윈도우즈 프로그래밍 특론
메모리와 스레드
가상메모리 사용 방법
사용 방법
사용 예제
VirtualAlloc[메모리생성]
LPVOID lpAddress;
lpAddress = VirtualAlloc(NULL,
1024, MEM_RESERVE,
PAGE_NOACCESS);
VirtualLock[페이지예약]
BOOL vLock;
vLock = VirtualLock(lpAddress,
1024);
데이터를 페이지에 기록
데이터를 사용함
VirtualUnlock[페이지예약취소]
VirtualFree[페이지없앰]
윈도우즈 프로그래밍 특론
메모리 사용
VirtualUnlock(lpAddress, 1024)
VirtualFree(lpAddress, 1024,
MEM_DECOMMIT);
메모리와 스레드
가상 메모리 함수
VirtualAlloc
~ 가상 메모리 영역을 예약(RESERVE)하거나 사용(COMMIT)하는
데 사용
VirtualLock
~ VirtualAlloc에 의하여 할당된 메모리를 사용할 있도록 위탁을 받
겠다는 의미
VirtualUnlock
~ 위탁을 해제
VirtualFree
~ VirtualAlloc으로 할당된 메모리 영역을 자유영역으로 만들고자 할
때 호출
VirtualProtect
~ 사용 페이지에 한하여 접근 제어 속성을 변경하는데 사용
VirtualQuery
~ 할당된 페이지들에 대한 정보를 얻어오는데 사용
윈도우즈 프로그래밍 특론
메모리와 스레드
VirtualAlloc 함수
▣ 가상 메모리 할당
LPVOID VirtualAlloc(
LPVOID lpAddress, // 예약하거나 위탁받고 싶은 주소
DWORD dwSize,
// 메모리 크기
DWORD flAllocationType, // 메모리 Allocation 형태
DWORD flProtect // 보호모드 설정 };
메모리 할당 형태 – flAllocationType
MEM_COMMIT : 디스크가 메모리를 만들어 위탁. 만일 현재 위탁하여는 페
이지가 이미 위탁받았다면 그때는 사용을 금함.
MEM_RESERVE : 메모리를 예약. 기존에 사용하던 페이지를 그대로 예약
한다는 의미.
MEM_TOP_DOWN : 가장 최근에 맞게 메모리 만듦.
보호모드 설정 – flProtect
PAGE_READONLY : 읽기 전용으로
PAGE_READWRITE : 읽기 쓰기 전용으로
PAGE_NOACCESS : 다른 곳에서 사용을 할 수 없도록 접근 불가.
윈도우즈 프로그래밍 특론
메모리와 스레드
VirtualLock, VirtualUnlock, VirtualFree 함
수▣ 메모리를 어떤 변수에 위탁
BOOL VirtualLock (
LPVOID lpAddress, // 위탁을 받는 포인터
DWORD dwSize,
// 위탁을 받는 메모리 크기 };
▣ 위탁 해제
BOOL VirtualUnlock (
LPVOID lpAddress, // 위탁을 해제하는 포인터
DWORD dwSize,
// 위탁을 해제하는 메모리 크기 };
▣ 메모리 해제
BOOL VirtualFree (
LPVOID lpAddress, // 메모리 주소 포인터
DWORD dwSize,
// 메모리 크기
DWORD dwFreeStyle // 해제하는 형태 };
해제 형태 – dwFreeStyle
MEM_DECOMMIT : 예약만 취소
MEM_RELEASE : 완전히 메모리 삭제
윈도우즈 프로그래밍 특론
메모리와 스레드
GlobalAlloc와 LocalAlloc 함수
►GlobalAlloc : Global Heap 영역에 메모리 할당
LocalAlloc : Local Heap 영역에 메모리 할당
윈도95 이상에서는 차이 없이 가상 메모리 형태로 사용.
즉, Heap 영역에 메모리 할당.
► VirtualAlloc와 GlobalAlloc, LocalAlloc의 차이점
VirtualAlloc은 64비트 메모리 주소 반환
GlobalAlloc과 LocalAlloc은 32비트 메모리 주소 반환
윈도우즈 프로그래밍 특론
메모리와 스레드
GlobalAlloc 계열 함수
▣ 메모리를 새로 만드는 함수
GLOBAL GlobalAlloc (
UINT uFlags, // 메모리에 적재 속성
DWORD dwBytes, // 적재할 메모리 크기 };
적재 속성 - uFlags
GEM_MOVEABLE : 이동이 가능하게 메모리 만듦.
GEM_DDESHARE : 두 갱의 프로그램에서 공유.
▣ 설정된 메모리 Lock ~ 현재 메모리를 움직이지 못하게 하고 내가 사용할 때 다른 곳
에서 접근 및 수정 등을 할 수 없게 핸들을 내가 갖겠다는 뜻.
LPVOID GlobalLock (
HGLOBAL hMem // 메모리 핸들 };
▣ Lock 했던 메모리 해제
BOOL GlobalUnlock ( HGLOBAL hMem // 메모리 핸들 };
▣ 메모리 해제
HGLOBAL GlobalFree ( HGLOBAL hMem // 메모리 핸들 };
윈도우즈 프로그래밍 특론
메모리와 스레드
GlobalAlloc 함수 사용 예제
LPSTR lpMem; // 만들 메모리
LPSTR lpHandle; // 메모리를 핸들링하는 함수
lpMem = GlobalAlloc( GMEM_MOVEABLE, 1024 ) ;
// 메모리를 설정함. 메모리가 움직일 수 있도록 함.
lpHandle = GlobalLock( (LPSTR)lpMem ); // 메모리를 예약함.
// 메모리 사용
………...
GlobalUnlock( lpMem ); // 메모리의 예약을 해제함.
GlobalFree( lpMem ); // 메모리의 메모리를 지움.
윈도우즈 프로그래밍 특론
메모리와 스레드
Heap에 메모리 사용 함수
▣ 상황
애니메이션이나 동영상을 사용하는 프로그
램이 있다면 먼저 디스크 영역에서 데이터
를 올려서 빠른 속도로 처리하여 화면에
출력해 주어야 함.
해결책 : Heap 영역에 데이터 적재
윈도우즈 프로그래밍 특론
메모리와 스레드
HEAP 관련 함수
▣ 메모리를 새로 만드는 함수
HANDLE HeapCreate( DWORD flOptions, DWORD dwInitialSize,
DWORD dwMaximumSize);
▣ HEAP을 메모리에 할당
LPVOID HeapAlloc( HANDLE hHeap, DWORD dwFlags, DWORD dwBytes );
▣ HEAP 메모리의 영역 크기 변경
LPVOID HeapReAlloc( HANDLE hHeap, DWORD dwFlags, LPVOID lpMem,
DWORD dwBytes );
▣ HEAP 메모리의 크기 얻기
LPVOID HeapSize( HANDLE hHeap, DWORD dwFlags, LPCVOID
lpMem );
▣ HEAP 메모리의 영역 해지 및 제거
BOOL HeapFree( HANDLE hHeap, DWORD dwFlags, LPVOID lpMem );
BOOL HeapDestroy( HANDLE hHeap );
윈도우즈 프로그래밍 특론
메모리와 스레드
배열에 메모리 할당 new
C++의 동적 메모리 할당 방법
new/delete 연산자 : 프로그램 실행 시에 동적으로 메모
리를 할당하거나 반환함.
new 연산자 : 원하는 타입의 객체를 생성하고 그에 대한
포인터를 반환
- 생성할 수 없으면 0을 반환
delete 연산자 : new로 생성된 객체에게 할당된
기억장소를 반환
※
클래스의 크기에 맞게 메모리를 할당 해 줌.
윈도우즈 프로그래밍 특론
메모리와 스레드
new 예제
배열 생성
Int *data;
data = new int[16];
..
delete [] data;
클래스 생성
CTestDlg *pDlg;
pDlg = new CTestDlg;
pDlg->DoModal();
delete pDlg;
윈도우즈 프로그래밍 특론
메모리와 스레드
메모리 공유하기
메모리 공유(Sharing) 또는 메모리 매핑(Mapping)
~ 하나의 메모리 파일을 만든 다음 이 메모리 파일을 두 개
이상의 모듈에서 공유하여 데이터를 서로 전달하고 받을 때
사용하는 방법.
<개념> 메모리를 파일 처럼 오픈 하여 한쪽에서는 기록하고,
다른 한쪽에서는 읽는 방법으로 데이터를 공유하는 방법.
파일 = 메모리
메모리 공유를 위해 메모리 매핑 파일(Memory Mapping
File) 생성.
윈도우즈 프로그래밍 특론
메모리와 스레드
메모리 공유하기
데이터를 기록하는 측의 프로그램 코드
HANDLE m_hMapping;
LPVOID m_pViewOf;
m_hMapping = CreateFileMapping ((HANDLE)0xFFFFFFFF, NULL,
PAGE_READWRITE, 0, 10240, “ExMemMap” );
m_pViewOf = MapViewOfFile ( m_hMapping, FILE_MAP_READ |
FILE_MAP_WRITE, 0, 0, 0 );
// m_pViewOf 포인터에 데이터를 기록
strcpy ((char *)m_pViewOf, “Text Data…” );
데이터를 읽는 측의 프로그램 코드
HANDLE m_hMapping;
LPVOID m_pViewOf;
m_hMapping = OpenFileMapping ( FILE_MAP_READ | FILE_MAP_WRITE,
FALSE, “ExMemMap” );
m_pViewOf = MapViewOfFile ( m_hMapping, FILE_MAP_READ |
FILE_MAP_WRITE, 0, 0, 0 );
Cstring data = (LPSTR)m_pViewOf;
// data에 “Text Data…”의 문자열이 설정됨.
윈도우즈 프로그래밍 특론
메모리와 스레드
메모리 매핑 파일 관련 함수
▣ 메모리 매핑 파일 생성
HANDLE CreateFileMapping ( HANDLE hFile, // 파일 매핑 핸들
LPSECURITY_ATTRIBUTES lpFileMappingAttributes, // 보안 속성
DWORD flProtect, // 읽기 쓰기 옵션 플래그
DWORD dwMaximumSizeHigh, // 상위 메모리 오프셋 최대 크기
DWORD dwMaximumSizeLow, // 하위 메모리 오프셋 최대 크기
LPCSTR lpName // 매핑 파일명 };
▣ CreateFileMapping과 대응되는 함수
HANDLE OpenFileMapping (
DWORD dwDesiredAccess, // 접근 모드
BOOL bInheritHandle, // 기존 핸들 사용
LPCSTR lpName // 매핑 파일명 };
▣ 공유할 메모리 페이지와 데이터를 기록할 포인터를 연결하는 함수
LPVOID MapViewOfFile (
HANDLE hFileMappingObject, // 매핑 파일 핸들
DWORD dwDesiredAccess, // 접근 모드
DWORD dwFileOffsetHigh, // 메모리 파일의 상위 오프셋 번지
DWORD dwFileOffsetLow, // 메모리 파일의 하위 오프셋 번지
DWORD dwNumberOfBytesToMap // 매핑하고자 하는 크기 };
윈도우즈 프로그래밍 특론
메모리와 스레드
[예제] 메모리 매핑 파일 처리
메모리 파일을 View와 대화 상자에서 공유
View에서 수정된 데이터가 그대로 대화 상자에 반영
대화 상자는 모달리스 형식으로 운영
윈도우즈 프로그래밍 특론
메모리와 스레드
[예제] 메모리 매핑 파일 처리 - 코드
윈도우즈 프로그래밍 특론
메모리와 스레드
스레드란 ?
스레드(Thread)란 하나의 작업 단위
독립적인 작업 단위
프로세스에서 실행되는 하나의 일관된 소스 코드
경량 프로세스( LWP : Light Weight Process )
<예> 워드 프로세서 작업 + 인터넷 다운로드 작업
프린터 도중에 문서 편집 작업 ? + 인터넷을 통한 데이터 다운로드 ?
프린터 출력 스레드, 입력 작업 스레드
+ 다운로드 스레드
멀티 스레드(Multi-Threaded)
윈도우즈 프로그래밍 특론
메모리와 스레드
스레드의 구동
① 스레드 프로그램 작성
UINT ThreadProc ( LPVOID lParam ) // 사용자 정의 함수
{
// 스레드의 작업 내용 코딩
}
② 스레드 기동하기
- CMExThreadView에서 ThreadProc을 구동
AfxBeginThread ( ThreadProc, this ); // WIN API 함수
③ 스레드에 데이터 넘기기
- 전역 변수 이용
- lParam 이용
UINT ThreadProc ( LPVOID lParam ) // 사용자 정의 함수
{
CMExThreadView *pView = (CMExThreadView *)lParam;
// 스레드 내용 코딩
}
윈도우즈 프로그래밍 특론
메모리와 스레드
[예제] 스레드 프로그램
SDI 형식의 프로그램
메뉴의 “스레드 시작”에 의해 스레드 시작
메뉴의 “스레드 종료”에 의해 스레드 중단
스레드 – 화면에 랜덤한 크기의 상자를 임의의 색으로 그리는 스레드
윈도우즈 프로그래밍 특론
메모리와 스레드
[예제] 스레드 프로그램 코드
윈도우즈 프로그래밍 특론
메모리와 스레드
스레드의 동기화
MFC에서 멀티스레딩을 위해 제공하는 클래스
- 동기 클래스 - CSyncObject, CSemaphore, CMutex,
CCriticalSection, CEvent
- 동기화된 접근을 허용 하는 클래스 – CMultiLock, CSingleLock
Thread의 sync 방법
- 일반적으로 thread는 자신을 sleep 상태로 만들어 다른 thread와
sync조정
. thread가 sleep 상태로 되면 더 이상 schedule 되지 않음
. 자신을 sleep 상태로 만들기 전에 “special event”가 일어나
면 깨우기를 요청함
. 요구한 상태가 발생하면 OS는 CPU를 할당하여, 그 스레드
를 깨우고 scheduling 한다.
윈도우즈 프로그래밍 특론
메모리와 스레드
크리티컬 섹션(Critical Section)
같은 크리티컬 섹션을 가지고 있는 스레드 중에 한 개의 스레드만
작업할 수 있게 해줌. (단점, 단일 프로세스 내에서만 사용 가능)
CCriticalSection 클래스 이용
Thread1
Thread2
Thread3
Critical Section
Thread 1이 critical section안에 있음
(critical section structure를 변경 중)
Critical
Section
Structure
윈도우즈 프로그래밍 특론
Thread 2이 critical section에 도착
(Thread 1때문에 들어가지 못함 )
Thread 3 은 아직 critical section에
도착하지 못함
메모리와 스레드
뮤텍스(Mutex)
커널 객체로서 Multual Exclusion의 약자
multiple process내의 thread들 간에 사용 가능
프로세스간 동기화 가능.
크리티컬 섹션과 유사 – 여러 개의 스레드가 한 개의 뮤텍
스를 공유하고, 이것을 가지고 있는 한 개의 스레드만 작업.
크리티컬 섹션은 여러 프로세서가 동시에 접근하는 DLL
과 같은 파일에서는 사용 불가.
CMutext 클래스 이용
윈도우즈 프로그래밍 특론
메모리와 스레드
세머포어(Semaphore)
크리티컬 섹션, 뮤텍스 오직 한 개의 스레드만 동작
다수의 원하는 개수의 스레드 만큼 동시에 작업할 수 있
도록 함.
CSemaphore 클래스 이용
리소스의 사용 카운트 수를 물어볼 수 있도록 함.
생성시 스레드의 번호와 최대 허용 가능한 스레드의 개
수를 정의 함.
윈도우즈 프로그래밍 특론
메모리와 스레드
이벤트(Event)
동기화 개체 중 가장 기본적인 형태
크리티컬 섹션, 뮤텍스, 세머포어는 데이터 접근을 제어
하기 위해 사용
이벤트는 어떤 동작이 완료되었음에 대한 시그널 사용
CEvent 클래스 이용
Manual-reset 이벤트 및 Auto-reset 이벤트 사용 가
능. 각각 동작 완료를 기다리는 스레드 모두(수동-리셍
이벤트) 또는 하나에게만(자동-리셋 이벤트) 시그널.
한 스레드가 초기화 하고, 작업 완료 후 다른 스레드에
게 나머지 작업을 시작하라고 알릴 때 사용.
윈도우즈 프로그래밍 특론
메모리와 스레드
사용할 동기화 클래스 선택 요령
프로그램이 어떤 리소스에 접근하기 위해서 다른 일이
발생하기를 기다릴 필요가 있는가 ?
CEvent 사용
동시에 여러 개의 클래스가 한 개의 리소스에 접근할 필
요가 있는가 ?
CSemaphore 사용
한 개 이상의 프로그램이 리소스에 접근하는가 ?
CMutext 사용
윈도우즈 프로그래밍 특론
메모리와 스레드
[예제] MultiThread
두개의 스레드를 운영하는 방법 – Critical Section,
Mutex 사용 예제
MakeString : 문자열을 생성하는 스레드
DisplayString : 생성된 문자열을 표시하는 스레드
윈도우즈 프로그래밍 특론
메모리와 스레드
[예제] MultiThread - 코드
윈도우즈 프로그래밍 특론
메모리와 스레드
[예제] MultiThread - 코드
윈도우즈 프로그래밍 특론
메모리와 스레드
- The End 윈도우즈 프로그래밍 특론
메모리와 스레드