8장 유저모드의 동기화 이 부분이 아마 이 책 전체 내용 중에서도 가장 hot한(?) 챕터가 아닐까 한다. 
명관씨가 나한테 이 부분을 지정해준 덕에 기초 부분을 좀 더 확실히 다지는 기회가 되어서 좋았다. 

공부 하고 싶던 책이 스터디 주제로 선정되니까 확실히 예전보다 더 의욕적으로 공부하게 되어서 좋다.

자료 앞부분에는 책에서 이야기 하지 않는 내용도 추가로 더 덧붙임.
다른 책 스터디할 때 이렇게까지 적극적이었던 적이 많이 없었는데 ㅎㅎ


Posted by leafbird 트랙백 0 : 댓글 0

댓글을 달아 주세요

아꿈사 스터디 진도에 따라 책 내용을 개인적으로 정리할 생각입니다.

 

1. 에러 핸들링

1장은 내용이 그렇게 많지 않다. 윈도우 API가 에러를 반환하는 방식 (GetLastError류)과, 이와 유사한 방식으로 자신의 에러 코드를 정의할 수 있는 방법을 설명. 이보다는 가장 마지막에 나오는 MC.exe에 대해서 정리하려고 함. (뭐냐..)

예전에 visual studio 툴 자체에 대해서 공부하다가 코드를 컴파일 하는 cl.exe, 리소스를 컴파일 하는 rc.exe 외에 메시지를 컴파일 하는 mc.exe가 있다는 사실을 알고, 언젠가 기회가 되면 게임 수출할 때 로컬라이제이션 작업에 사용해 보리라 생각했던 적이 있다. 그리고는 그 다음 프로젝트 시작할 때 실제로 문자열 테이블 생성 작업에 쓰려고 본격적으로 리서치를 했던 적이 있지만 결국 사용되지 않고 drop 되었는데, 주된 이유가 두 가지였던 것으로 기억한다.

  1. 게임 클라이언트에 들어가는 문자열들의 최초 형태는 각 나라별로 엑셀파일에 정리되는 게 가장 좋기 때문에 mc를 사용한다고 해도 엑셀에서 mc 스키마로 한 번, mc에서 컴파일한 바이너리로 한 번 총 두 차례 변환을 거쳐야 하는 것이 부담스럽다.
  2. mc.exe가 입력으로 받아들이는 문자열 데이터는, 번역하고자 하는 모든 나라의 데이터들이 전부 같은 파일에 담겨야 한다. 앞서 이유에서 말한 두 차례의 변환과정을 자동화 할 때 이렇게 처리한다고 해도, 한 나라의 번역만 업데이트되도 다른 모든 나라의 언어 리소스를 함께 넣어 새로 빌드 하는 것이 부담스럽다.

혹시나 mc.exe를 게임 로컬라이징에 써볼까 하고 생각하는 분들은 참고가 되길 바란다.

2. 문자와 문자열로 작업하기

유니코드와 인코딩에 대한 이야기. 그 외 버퍼 오버런을 방지하기 위해 vs2005에서부턴가 새로 들어간 strsafe.h 헤더에서 제공하는 새로운 API들에 대한 이야기들. 윈도우에서 문자를 다룰 때 사용할 수 있는 동일한 기능의 함수가 여러 개 존재 하는데, 이들에 대한 우선순위를 확실히 정해주니까 좋았다.

  • 53p. strsafe에 대한 include구분은 다른 include 구문보다 반드시 뒤쪽에 위치되어야 한다. (컴파일 할 때 경고를 나타내기 위해서인 듯)
  • 기존의 c런타임 문자열 함수보다는 (strcpy) strsafe.h의 안전 문자열 함수를 사용하고 (strcpy_s), 문자열 잘림이나 남는 버퍼 공간 처리 등을 좀 더 세밀하게 다루고 싶다면 StringCch… 계열의 함수를 사용하라. (StringCchCopy) 하지만 애초에 문자열 잘림이 발생하지 않게 하는 것이 더 좋겠지.
  • 인코딩 변환에 쓰이는 MultiByteToWideChar, WideCharToMultiByte 함수의 상세한 설명. 멀티바이트 코드로 변환하다가 변환 불가능한 문자가 존재할 경우의 예외처리 등에 대한 설명이 있다.
  • 그 이에 IsTextUnicode (BOM 없는 문자열을 코드 패턴으로 어느 인코딩인지 추측하는 함수)나 언어 로케일을 포함해 문자비교를 할 수 있는 CompareString 같은 함수는 처음 알게 됨.

요즘은 문자열을 이렇게 저 수준으로 다루는 일이 많이 없지만.. 한 번 읽어두면 도움 될 내용이 제법 있었다.

3. 커널 오브젝트

커널 오브젝트를 제대로 공부한 것은 이번이 처음이다. 그냥 프로세스나 스레드 내지는 동기화 객체들 일부를 커널 오브젝트라고 부르더라.. 하는 것만 알고 있었을 뿐이었는데 이렇게 명확히 정리하니 속이 다 후련하다.

커널 오브젝트는 커널에 의해 할당된 간단한 메모리 블록이다. 커널 오브젝트에 대한 세부 정보들을 저장하고 있다. (커널 오브젝트는 실제 커널 내의 리소스에 대한 통계 정보 등을 접근하기 위한 인터페이스 정도의 역할이다.) 커널 오브젝트는 프로세스가 아니라 커널에 의해 소유되기 때문에 프로세스가 종료된다고 해서 생성한 커널 오브젝트가 반드시 함께 삭제되는 것은 아니다. 커널 오브젝트는 자신을 생성한 프로세스보다 더 오랫동안 삭제되지 않고 남아 있을 수 있다. 하지만 보통 내가 게임을 만들어 오면서 코딩하는 수준 안에서는 프로세스간에 커널 오브젝트를 공유하는 일이 없었기 때문에, 대부분 프로세스의 종료시점에 커널 오브젝트도 파괴된다.

커널 오브젝트의 종류를 모두 다 보여주는 WinObj라는 툴도 있으니 여기서 종류를 확인해 볼 수 있다. 코딩하면서 어떤 오브젝트가 커널 오브젝트인지 여부를 결정하는 가장 간단한 방법은 생성함수가 보안 특성을 지정하는 배개변수를 입력으로 받는지를 확인하는 것이다.(74p)

커널 오브젝트는 사용 카운트(use count)를 가진다. 이 값은 일반적인 레퍼런스 카운트(reference count)와 동일하게 동작한다. 여러 프로세스에서 참조하면 값이 올라가고, CloseHandle을 하면 값이 감소한다. 이 값이 0이 되면 커널 오브젝트는 파괴된다. 72p, 78p에 해당 내용이 설명되어 있고, 이후에 핸들 테이블에 대해 설명할 때도 몇 번 언급된다. 스터디 시간에 ‘커널 오브젝트는 프로세스보다 더 오래 남아있을 수 있다’는 특성 때문에, 제대로 해제해 주지 않으면 누수(leak)현상이 발생 하는 것이 아닌가? 하는 의문이 있었는데, 프로세스의 종료시점에 핸들 테이블에 지정된 커널 오브젝트의 핸들을 모두 Close하기 때문에 누수는 일어나지 않는다. (79p에 써있다.)

동일 애플리케이션이 여러 번 수행되는 것을 방지하기 위해 명명된 커널 오브젝트를 사용하는 것(92p)은 게임 클라이언트에도 종종 사용하는 기법이다. 이에 덧붙여 명명된 커널 오브젝트를 사용할 때 private namespace를 이용하여, 오브젝트 이름을 알더라도 권한이 낮은 프로세스가 접근하지 못하게 하는 방법이 소개되어 있다.

프로세스간에 오브젝트 핸들을 상속하거나 복사하는 방법도 설명되어 있는데, 나는 자주 사용할 것 같진 않다. 핸들을 복사할 때 특정 권한만으로 제한해서 복사할 수도 있다.

핸들로 표현되는 리소스라고 해서 모두 다 CloseHandle로 해제처리 가능한 것은 아니다. 101페이지에 예시가 등장.

4. 프로세스

4장이 내용이 엄청 길다.

114. VC++ 프로젝트 설정에서 /SUBSYSTEM 설정에 따라 콘솔 프로그램인지 윈도우프로그램인지가 결정되고 프로그램 entry point도 main/WinMain이 결정되는데, 이 설정란을 아예 비워주면 코드에 존재하는 함수를 보고 적절한 설정으로 자동 결정된다.

143. CreateProcess의 엄청난 인자 리스트를 설명하는 내용 중간에, 콘솔 프로세스가 새로운 콘솔 프로세스를 생성할 때 CREATE_NEW_CONSOLE 인자를 사용하면 독립된 별개의 콘솔 윈도우를 생성하게 할 수 있다는 설명이 있다. 알아두면 좋을 듯.

144. IsWow64Process 함수 : 프로세스가 64비트 운영체제에서 32비트 모드로 실행중인지 확인할 수 있다.

153. 스터디 시간에 많은 논란이 됐던 부분이다.

많은 개발자들이 프로세스나 스레드 핸들을 삭제하면 프로세스나 스레드가 종료될 것이라 생각하지만 이것은 절대로 사실이 아니다. 핸들을 삭제하는 것은 단순히 프로세스와 스레드의 통계적인 자료에 더 이상 관심이 없다는 사실을 시스템에게 알려주는 것일 뿐이다. 프로세스와 스레드는 자체적으로 종료될 때까지 계속해서 수행된다.

이것 때문에 커널 오브젝트의 사용 카운트는 레퍼런스 카운트와 다른 의미가 아니냐 하는 의문이 더 강해졌는데, 실제로 프로세스(스레드) 리소스와 프로세스(스레드) 리소스의 커널 오브젝트를 약간 별개로 두고 이해해야 한다. 커널 오브젝트가 파괴된다고 해도 그것이 가리키는 리소스가 항상 같이 파괴되는 것이 아니라는 이야기다. 책에서 '프로세스 커널 오브젝트의 파괴'와 '프로세스의 종료'라는 말이 나오는데, 파괴와 종료는 아마 원서에서 destroy, terminate일거 같은데 번역되면서 어감이 비슷해져 더 혼란스러운 감이 있다. 커널 오브젝트는 사용 카운트값이 0이 될 때 정확히 파괴(destroy)된다. 하지만 프로세스 자체는 커널 오브젝트가 파괴된 뒤에도 여전히 동작할 수 있으며, 155페이지 하단에 정리된 4가지 방법에 의해 종료(terminate)된다.

158, 159. 프로세스의 종료에 대해 이야기 하면서, 프로세스가 사용하던 모든 리소스는 환벽하게 정리된다는 내용이 다시 언급되고 있다. 커널 오브젝트, 사용자 오브젝트, GDI 오브젝트 등의 리소스 일체가 프로세스 종료시 자동으로 정리된다. 커널 오브젝트도 실수로 핸들을 close하지 않았더라도 따로 타 프로세스로 공유한 적이 없다면 반드시 파괴된다.

162. 커널 오브젝트의 사용 카운트를 공부하고 나면 당연히 이해할 수 있는 내용인데, CreateProcess로 자식 프로세스를 생성하자 마자 바로 자식 프로세스의 hProcess와 hThread 핸들을 닫아주는 것이 맞다. 이렇게 해도 자식 프로세스가 종료되는 것은 아니고, 접근할 일 없는 커널 오브젝트의 사용 카운트는 줄여 주는 것이 좋기 때문이다.

비스타 이후 도입된 UAC 시스템 에서의 권한 처리에 대한 설명들이 자세히 적혀있음. 클라이언트 배포 작업하면 볼 일이 많은데 나중에 참고할 것. API만 잘 이해하면 큰 혼동은 없으니 따로 정리하지는 않는다.

5.잡

잡 오브젝트의 존재를 처음 알았다. virtualization 소프트웨어를 개발할 때 많이 쓰이고, 크롬처럼 독립된 프로세스 단위로 프로그램을 만들 때도 쓰인다고 한다. 나중에 병렬처리를 스레드 단위가 아니라 프로세스 단위로 하게 되면 유용하게 사용할 수 있을 것 같다. visual studio도 빌드할 때 cl.exe를 별도 프로세스로 실행하는데, 책을 읽어보면 잡을 사용하고 있지는 않다. (197p) 아마도 legacy를 이어받아 개발했기 때문일것으로 예상되는데, 아마 vs2010에는 잡을 사용했을 것 같음.

간단하게 정리하면 잡 오브젝트란 여러 프로세스를 담아둘 수 있는 컨테이너 같은 개념이다. 프로세스를 잡에 묶어서 할 수 있는 대표적인 세 가지 작업은 아래와 같다.

  1. 권한 조절. 다른 프로세스에 접근하지 못하게 하거나 특정 리소스에 대한 접근을 제한할 수 있고, 사용할 수 있는 메모리가 cpu 타임도 조절할 수 있다.
  2. 통계 획득. job 안에서 실행되는 프로세스에 대한 메모리 사용량, io 횟수 정보, cpu 타임 등을 얻을 수 있다.
  3. 이벤트 통지. job 안에서 실행되는 프로세스의 주요 이벤트들을 핸들의 시그널 상태로 얻어낼 수도 있고, 자세한 여러가지 이벤트는 IOCP를 이용해 통지받을 수 있다.

이중 2번의 프로세스 통계 확인은 굳이 job 내의 자식 프로세스가 아니라 자기 자신의 정보를 구하는 것도 요긴해 보이는데, GetProcessTime이나 GetProcessIoCounters함수를 이용하면 얻을 수 있다. (198p)

Posted by leafbird 트랙백 0 : 댓글 1

댓글을 달아 주세요

  1. addr | edit/del | reply Favicon of https://devnote.tistory.com BlogIcon leafbird 2012.07.02 18:35 신고

    메시지 컴파일러의 사용은 아래 링크 참조.

    http://www.codeproject.com/Articles/4166/Using-MC-exe-message-resources-and-the-NT-event-lo


웹서버와 게임서버의 통신 부분은, 제가 몰랐던 부분이 많네요. (웹쪽을 잘 몰라서..)

피드백을 받으면서 생각들을 많이 정리하고 있습니다. 
지금도 많은 분들이 좋은 피드백을 해 주셨는데, 
더 좋은 의견이나 제안이 있다면 공유해 주세요~
 
PT에 제안된 것과 비슷한(혹은 더 나은) 생각을 하시는 분들이 여럿 계시는군요 :)
역시 아이디어를 혼자서 머리속으로만 생각하고 있는 것보다
많이 공유할 수록 더 진화 하는 것 같습니다. -_-)b
 

덧. 크롬 웹스토어에서 게임을 만드는 기반 기술은 NaCl이라고 부르는 구글 Native Client API인가보군요.
이제야 알았습니다.... 따로 포스팅 해야겠군;

Posted by leafbird 트랙백 0 : 댓글 0

댓글을 달아 주세요


Posted by leafbird 트랙백 0 : 댓글 0

댓글을 달아 주세요


[아꿈사/110528] 멀티코어cpu이야기 5,6장
View more presentations from sung ki choi
Posted by leafbird 트랙백 0 : 댓글 0

댓글을 달아 주세요

[아꿈사발표자료] TAOCP 1.3.2 MIX 어셈블리 언어 연습문제 (110312)
View more presentations from sung ki choi

아꿈사 발표준비 빡시다.

일주일 내내 탱자탱자 놀다가 바로 전날 다 하려니까 너무 후달림.

한 번 발표할 때마다 명이 짧아지는 느낌이야 ㅠ

다음엔 꼭 일찍 준비해야지!

Posted by leafbird 트랙백 0 : 댓글 0

댓글을 달아 주세요

110212 [아꿈사발표자료] taocp#1 1.2.8. 피보나치수열
View more presentations from sung ki choi.

Posted by leafbird 트랙백 0 : 댓글 2

댓글을 달아 주세요

  1. addr | edit/del | reply Favicon of http://ohyecloudy.com/pnotes BlogIcon ohyecloudy 2011.02.18 20:38

    발표자료 정말 잘 만들었네. 짱.
    자유 주제 발표 꺼리 생기면 얘기해~

    • addr | edit/del Favicon of https://devnote.tistory.com BlogIcon leafbird 2011.02.21 10:08 신고

      만드는 법 전부 다 형한테 배운거지요 ㅎ
      네 꺼리 생기면(?) 이야기 할게요~ ㅎㅎ
      이번 스터디에 형 오셨었나요? 저는 일이 있어서 앞에 한시간만 듣고 먼저 갔어요 ^^;