728x90

이번 내용은 MMF(Memory Mapped File) 을 이용한 프로세스간의 메모리 공유입니다.
 
일전에 설명드렸다시피(링크) Win32 이상의 환경에서는
 
프로세스의 주소공간은 독립적으로 관리되기 때문에
 
어떤 하나의 프로세스는 다른 프로세스의 주소공간을 공유할 수 없습니다.
 
A라는 프로세스의 0x1234라는 주소값은 B라는 프로세스의 0x1234와는 전혀 다른 공간입니다.
 
이런 메모리 관리 구조는 OS를 안정적이고 견고하게 만들어주었지만
 
한편으로는 프로그램 사이에 정보를 주고 받기가 어렵게 되어버렸습니다.
 
프로세스 사이에 정보를 공유하기 위해서 MMF라는 방식을 사용합니다.
 
MMF는 이름 그대로 파일을 메모리에 맵핑하기 위해서 사용되는 기법입니다.
 
간단하게 설명하자면, 파일을 열어서 해당 파일을 메모리에 맵핑시켜서 사용하는 것입니다.
 
MMF를 이용해서 하드디스크의 파일을 프로세스의 주소 공간에 연결해서 사용이 가능합니다.
 
하지만 여기서는 파일을 여는 것이 아닌 프로세스가 서로 접근할 수 있는 메모리의 공유 영역을
 
생성하기 위해서 사용하겠습니다.
 
File Mapping object는 Named kernel object로 생성되면 모든 프로세스에 영향을 줍니다.
 
뮤텍스와 유사한데 한 쪽 프로세스에서 뮤텍스를 생성하면 모든 프로세스에 영향을 주듯이
 
이것도 같은 이름의 File Mapping object는 어느 프로세스나 사용이 가능합니다.
 
전에 커널 영역은 접근이 불가능하다고 했는데,
 
Windows가 제공하는 함수들을 이용해서 정해진 방법으로
 
커널 오브젝트에 접근이 가능합니다.
 
그럼 예제를 먼저 보도록 하겠습니다.
 
일단 A 프로세스의 코드입니다.

 

그리고 B 프로세스의 코드입니다.

 

중요한 WndProc과 정의 부분만 캡쳐해서 올립니다.

 

일단 A 프로세스에서는 WM_CREATE부분에서 버튼 하나를 만들어주고

 

CreateFileMapping 함수를 이용해서 메모리 영역을 맵핑시키는데 중요한 것은

 

맨 처음 인자를 INVALID_HANDLE_VALUE(0xFFFFFFFF)로 주는 것이 핵심입니다.

 

일반적인 상황이라면 CreateFile에서 반환되는 핸들을 넣지만 여기서는 저 값을 넣어줍니다.

 

그리고 MapViewOfFile 함수를 이용해서 파일(여기서는 메모리의 일정 부분)의 뷰를

 

주소 공간에 맵핑시킵니다.

 

그럼 모든 준비는 끝나고 마우스로 버튼을 클릭하게 되면

 

MapViewOfFile 함수가 리턴하는 포인터에 문자열을 입력합니다.

 

_T("Message from ProcA")라는 문자열이 포인터가 가리키는 메모리 영역에 저장이 될 것입니다.

 

그리고 ProcB의 핸들(Window Handle)을 찾아서 거기에 메시지를 날립니다.

 

B에서 A가 기록한 문자열을 읽게 하기 위해서죠.

 

B 프로세스는 CreateFileMapping 대신에 OpenFileMapping을 사용하고 있습니다.

 

이미 생성된 object를 단순하게 열기만 할 경우에는 Open류의 함수를 이용하시면 됩니다.

 

WM_SHAREDMEMORY 메시지가 들어오면 B 프로세스 또한 MapViewOfFile 가 리턴한

 

포인터를 이용해서 해당 메모리 부분을 읽습니다.

 

일반적으로 A의 주소 공간과 B의 주소 공간은 완전히 격리되어있어서

 

A의 주소 공간을 B는 절대 볼 수 없지만 Name kernel object를 이용해서 공유가 가능해졌습니다.

 

그리고 종료시킬 때에는 시작시의 역순으로 UnmapViewOfFile 함수를 호출하고

 

CloseHandle로 열려진 핸들을 닫는 것으로 끝이 납니다.

 

어려운 것 같지만 차근차근 읽어보면 전혀 어렵지 않습니다.

 

Windows가 프로세스의 주소 공간을 실제 가상 메모리(실제 메모리)에 맵핑시켜주는데

 

이름을 갖는 커널 오브젝트가 같은 실제 가상 메모리에 연결되는 점을 이용해서

 

어디에서나 같은 가상 메모리를 가리키게 처리해주고 그걸 그냥 읽고 쓰기만 하는겁니다.

 

간단하게 보자면 A 프로세스가 파일에 기록을 하고 메시지를 날리면

 

B는 파일의 내용을 읽는 것으로도 프로세스간 데이터의 공유는 가능합니다.

 

하지만 그것은 조금 비효율적일 수 있기 때문에 위와 같은 방법을 이용해서 공유를 하는것이죠.

 

이것으로 MMF를 이용한 프로세스간 메모리 공유를 마치겠습니다.

 

 

출처 : http://psychoria.blog.me/40113892474 

728x90
728x90

std::chrono를 이용하여 원하는 fps로 동작하게 하는 코드 까먹을까봐 박제함.

 

 

#include <iostream>

#include <chrono>

#include <cstdint>

 

const int fps = 60;

 

using namespace std;

using namespace chrono;

using frame = duration<int32_t, ratio<1, fps>>;

using ms = duration<float, milli>;

 

int main()

{

    time_point<steady_clock> fpsTimer(steady_clock::now());

    frame FPS{};

 

    while (true)

    {

        FPS = duration_cast<frame>(steady_clock::now() - fpsTimer);

 

        if (FPS.count() >= 1)

        {

            fpsTimer = steady_clock::now();

            cout << "LastFrame: " << duration_cast<ms>(FPS).count() << "ms | FPS: " << FPS.count() * fps << endl;

        }

    }

    return 0;

}

 

출처 : https://www.gamedev.net/forums/topic/690860-60-fps-game-loop-using-stdchrono/

 

60 FPS game loop using std::chrono

Hi everyone, out of curiosity yesterday I was trying out chrono header with the goal of creating a 60fps loop, the code below is what I have so far and I wanted your opinion about it, if it is the proper way to do it, how it is usually done or how I could

gamedev.net

 

추가 : Making an accurate Sleep() function | computerBear (blat-blatnik.github.io)

 

728x90
728x90

사용 방법

 

결과

 

CLogMessage.h
0.00MB

728x90

'Basic Programming > C, C++' 카테고리의 다른 글

C++ - MMF(Memory Mapping File)  (0) 2020.05.21
C++ - 60fps로 동작하게 하는 코드  (0) 2020.03.11
C++ - 덤프 파일을 통한 사후 디버깅  (0) 2018.11.21
C++ - region, endregion  (0) 2018.08.03
C++ - Joystick 입력 받기.  (0) 2018.02.01
728x90

NDC 2012에 가서 들었던 내용인데...


우연히 PDF 발견


덤프 파일을 통한 사후 디버깅 실용 테크닉.pdf


728x90

'Basic Programming > C, C++' 카테고리의 다른 글

C++ - 60fps로 동작하게 하는 코드  (0) 2020.03.11
C++ - OutputDebugString()을 편하게 사용  (0) 2019.12.05
C++ - region, endregion  (0) 2018.08.03
C++ - Joystick 입력 받기.  (0) 2018.02.01
C++ - inline의 이해  (0) 2017.12.10
728x90

C#에 보면 #region 이라는 전처리기 지시문이 있다.

이를 사용하면 코드 편집기의 개요 표시 및 숨기기 기능으로 확장하거나 축소할 수 있는 코드 블록을 지정할 수 있다.


이를 Native C++에서도 사용할 수 있다.

이미 자주 사용하고 있는 #pragma 란 전처리기 지시문을 사용하여 할 수 있는데

#pragma region 문자열

#pragma endregion


그런데 이 #pragma 지시어가 이것을 지원하지 않는 다른 컴파일러에서 에러 또는 경고 메시지를 수반하지 않고서 #pragma 지시를 무시하도록 되어 있다고 하는데 어떤 사람은 gcc를 사용하는데 MS VC++로 된 파일을 컴파일 하는데 이 #pragma region 때문에 경고가 발생한다는 이야기를 본 적이 있다.



출처 : http://1and0.tistory.com/47

728x90

'Basic Programming > C, C++' 카테고리의 다른 글

C++ - OutputDebugString()을 편하게 사용  (0) 2019.12.05
C++ - 덤프 파일을 통한 사후 디버깅  (0) 2018.11.21
C++ - Joystick 입력 받기.  (0) 2018.02.01
C++ - inline의 이해  (0) 2017.12.10
C++ - deprecated 키워드  (0) 2017.09.15
728x90

Windows에서 개발한 코드이고, 간단하게 입력받아서 출력하는 코드이다.




#include <iostream>

#include <windows.h>


#pragma comment(lib, "winmm.lib")


int main()

{

    JOYINFOEX joystickInfo;


    ZeroMemory(&joystickInfo, sizeof(joystickInfo));

    joystickInfo.dwSize = sizeof(joystickInfo);

    joystickInfo.dwFlags = JOY_RETURNALL;//JOY_RETURNBUTTONS | JOY_RETURNX | JOY_RETURNY;


    while (true)

    {

        joyGetPosEx(JOYSTICKID1, &joystickInfo);


        char dbgMsg[MAX_PATH] = { 0, };

        sprintf(dbgMsg, "X : %d, Y : %d, Z : %d \n", joystickInfo.dwXpos, joystickInfo.dwYpos, joystickInfo.dwZpos);

  OutputDebugStringA(dbgMsg);


        if (joystickInfo.dwButtons & JOY_BUTTON1)

            OutputDebugStringA("JoyStick_Button_1 \n");


        Sleep(1);

    }

}

728x90
728x90

이번에 "게임 엔진 아키텍처" 라는 책을 읽으면서 좋은 내용이 있어서 정리해 놓는다.


나의 경우 inline 함수를 최적화를 생각하며 자주 사용하고 있다.

하지만 자세한 내용은 몰랐던 것 같다. ㅎㅎ


inline 함수가 다른 cpp 에서도 사용하기 위해서는 반드시 .h에 정의되어 있어야만 한다.

왜냐하면, 컴파일러가 inline 함수를 처리하려면 컴파일러가 함수의 정의 부분을 볼 수 있어야하는데, .cpp에 있다면 볼 수가 컴파일때에는 볼 수가 없기 때문이다.


// foo.h

inline int max(int a, int b)

{

return (a > b) ? a : b;

}


위의 경우 아주 올바른 inline 함수이다. 왜냐하면 컴파일러가 볼 수있다.


// 이 함수는 inline으로 정의하였지만, inline으로 처리되지 않는다.

// 왜냐하면 컴파일러가 함수의 구현을 볼 수 없기 때문이다.

// foo.h 

inline int max(int a, int b);


// foo.cpp

inline int max(int a, int b)

{

return (a > b) ? a : b;

}



이 내용은 전혀 몰랐던 것이기 때문에 공유한다.


728x90
728x90

서로 분할 작업을 하면서 모듈을 개발하다보면, 어떤 함수는 추가가 되고 어떤 함수는 없어지고 할 것이다.


이럴 때, 내가 만든 모듈에서 없어진 함수가 있다면 그것을 사용하는 개발자에게 경고를 띄워주고 싶을 것이다.




deprecated (함수 사용 경고) 이 키워드를 사용하면 된다.



사용법은 아래와 같다.








출처 : https://msdn.microsoft.com/ko-kr/library/044swk7y.aspx

728x90

+ Recent posts