Windows7은 사용자뿐만이 아닌 개발자에게도 편리한 기능을 가지고 있습니다.
그 중에 '대기 체인 분석' 이라는 것이 있습니다.
이것을 사용하면 프로그램을 종료 시켰는데는 프로세스는 죽지 않고 살아 있는 경우 어디서 문제가 되었는지 어느 정도 알아낼 수 있습니다.


이 프로그램은 제가 집에서 만든 서버 애플리케이션으로 X 버튼을 눌러서 종료시킵니다.


그런데 작업 관리자를 보면 프로세스가 아직 죽지 않았습니다(ProjectHF2.exe)

이 문제는 보통 워커 스레드를 사용하는 경우 특정 스레드가 죽지 않아서 발생하는 경우일것입니다.
그럼 어떤 스레드가 대기 상태에 있는지 알기 위해서 대기 체인 분석을 사용해보겠습니다.


리소스 버튼을 누르면 아래의 창이 나옵니다.


위 그림과 같이 프로세스를 선택 후 메뉴에서 '대기 체인 분석'을 선택합니다.


위와 같은 화면이 나오고 어떤 스레드가 어떤 이유로 대기하고 있는지 설명해줍니다.

이 기능은 Windows API 중 Wait Chain Traversal를 사용한 것입니다.
http://msdn.microsoft.com/ko-KR/library/ms681622(VS.85).aspx

어느 정도 제한은 있지만 이 API를 사용하면 데드락 상황도 판단할 수 있습니다.














저작자 표시
신고
by 흥배 2011.01.14 09:00
시스템 에러가 발생해서 GetLastError()을 사용해서 에러 값을 보면 숫자이기 때문에 어떤 에러인지 알기 힘듭니다. 이때 Win32 API인 FormatMessage를 사용하면 에러 문자열로 변환해주므로 에러 내용을 알기 편합니다.


제 경우는 네트웍에서 에러가 발생하면 아래와 같이해서 로그로 남기도록 합니다.

void Socket::SocketError( INT32 ErrCode, char* pFunctionName )
{
   // pFunctionName는 이 에러가 발생한 곳의 함수 이름
    LPVOID lpMsgBuf;
   
    FormatMessage
        (   FORMAT_MESSAGE_ALLOCATE_BUFFER
          | FORMAT_MESSAGE_FROM_SYSTEM
          | FORMAT_MESSAGE_IGNORE_INSERTS
        , NULL
        , ErrCode
        , MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)
        , (LPTSTR) &lpMsgBuf
        , 0
        , NULL );

    Logger->Write( "%s - GetLastError(%d - %s)", pFunctionName, ErrCode, lpMsgBuf );
}



이 API를 사용하기 위한 조건
OS : Windows 2000 이상
헤더파일 : winbase.h(windows.h에 포함되어 있음)
라이브러리 : kernel32.lib
DLL : kernel32.dll


자세한 내용은 아래를 참고해 주세요

MSDN : http://msdn.microsoft.com/en-us/library/ms679351%28VS.85%29.aspx



저작자 표시
신고
by 흥배 2010.12.06 09:00

CryptGenRandom는 랜덤 값을 생성하는 함수로 C 라이브러리의 rand와 비슷합니다.

틀린 점은 rand는 랜덤 값이 예측 가능하고 CryptGenRandom는 암호화 기능을 사용하여 예측 할 수 없는 랜덤 값을 생성해 줍니다.
(rand
의 경우 srand을 사용한 후 사용해야 이전과 중복되지 않은 패턴으로 랜덤 값을 생성합니다)

 


CryptGenRandom의 또 하나의 장점은 시드 값의 자료형 크기를 넘지 않는 랜덤 값을 생성합니다.
즉 시드 값의 자료형이 unsigned char라면 CryptGenRandom을 사용한 랜덤 값은 0 ~ 255 사이의 값만 나옵니다.


CryptGenRandom는 기존의 srand+rand의 조합에 비해서 장점이 있지만 단점도 있습니다. 단점은 성능입니다. CryptGenRandom가 암호화 기능을 사용하므로 rand에 비해서 느립니다. Win32 API에서는 어느 정도 차이가 나는지 잘 모르겠지만 똑 같은 기능이 있는 닷넷에서는 rnadCryptGenRandom의 성능 차이는 대략 100배 정도라고 합니다.

 

 

 

참고

Step By Step: Visual C++에서 난수 생성 방법
http://support.microsoft.com/kb/983137/ko

 

[MSDN] CryptoRandom 이야기
http://msdn.microsoft.com/ko-kr/magazine/cc163367.aspx

 

저작자 표시
신고
by 흥배 2010.11.08 09:00

시간 계산 어떻게 하시나요?

여러 가지 방법이 있겠지만 SYSTEMTIME을 사용하여 계산하는 경우라면 COleDateTimeCOleDateTimeSpan을 사용하여 계산하면 쉽게 할 수 있습니다.

COleDateTimeCOleDateTimeSpan ATL에 있는 라이브러리입니다.

 

 

COleDateTimeCOleDateTimeSpan을 사용하기 위한 조건

필요한 파일 : ATLComTime.h

 

 

예제

아래 예제는 지정된 시간에서 을 더한 시간을 계산합니다.

void UpdateTime( SYSTEMTIME& stPatchTime, INT32 wMinute )

{

COleDateTime PatchTime( stPatchTime.wYear, stPatchTime.wMonth, stPatchTime.wDay, stPatchTime.wHour, stPatchTime.wMinute, stPatchTime.wSecond );

 

COleDateTimeSpan SpendTime;

SpendTime.SetDateTimeSpan( 0, 0, wMinute, 0 );

PatchTime += SpendTime;

          

stPatchTime.wYear = PatchTime.GetYear();

stPatchTime.wMonth = PatchTime.GetMonth();

stPatchTime.wDay = PatchTime.GetDay();

stPatchTime.wHour = PatchTime.GetHour();

stPatchTime.wMinute = PatchTime.GetMinute();

}


 

COleDateTime은 생성자에서 SYSTEMTIME을 인자로 사용할 수 있습니다. 그러나 인자로 사용할 SYSTEMTIME의 값이 올바른 값인 경우만 사용할 수 있습니다. 예를 들어 아래와 같은 것을 인자로 넘기면 디버그 모드에서는 경고가 발생합니다.

SYSTEMTIME stTime;

stTime.wYear = 2010;

stTime.wMonth = 10;

stTime.wDay = 11;

 

COleDateTime CurTime( stTime );

// 이후 이것을 계산에 사용할 때 에러발생

 

 

저작자 표시
신고
by 흥배 2010.10.15 09:00

프로그램에서 현재 실행 중이 컴퓨터의 CPU에 대한 정보를 알아야 할 때가 있습니다.


예를들면

1. CPU 32비트인지 64비트인지

2. 코어가 몇 개 있는지

등등...


이런 정보를 알고 싶을 때는 Windows 2000 때까지는 GetSystemInfo를 사용했습니다.

그러나 GetSystemInfo 64비트 Windows에서 이 API를 사용하는 프로그램은 32비트 프로그램이라면 잘못된 정보를 가져옵니다. 그래서 32비트나 64비트 환경에 상관 없이 정확한 정보를 얻기 위해서는 GetNativeSystemInfo를 사용해야 합니다.

GetNativeSystemInfo 64비트 환경에서는 내부적으로 GetSystemInfo를 호출합니다.

 

 

 

 

GetNativeSystemInfo를 사용하기 위한 조건

 

OS : Windows XP 이상

필요한 파일 : windows.h

필요한 라이브러리 : kernel32.lib

필요한 dll : kernel32.dll

 

API를 사용할 때 헤더파일에 _WIN32_WINNT 선언이 0x0501 이상이어야 합니다.

#define _WIN32_WINNT 0x0501

 

 

예제

#include <iostream>

#include <windows.h>

 

int main()

{

           SYSTEM_INFO sInfo;

           GetNativeSystemInfo(&sInfo);

                    

           std::cout << "CPU 개수 : " << sInfo.dwNumberOfProcessors << std::endl;

           std::cout << "프로세스 아키텍처 : " << sInfo.wProcessorArchitecture << std::endl;

          

           getchar();

           return 0;

}


결과


저작자 표시
신고
by 흥배 2010.10.06 09:00

PathRemoveFileSpec API는 패스와 파일명이 있는 문자열

C:\\Users\\Heungbae\\Desktop\\임시.txt


라는 것이 있을 때 파일명인 임시.txt’을 제외한

C:\\Users\\Heungbae\\Desktop

문자열을 반환합니다.

즉 파일 이름까지 있는 전체 패스에서 이름만 제외한 패스 문자열을 만들어줍니다.

 

Ansicode를 사용할 때는 PathRemoveFileSpecA, Unicode를 사용할 때는 PathRemoveFileSpecW를 사용합니다.

 

 


PathRemoveFileSpec을 사용하기 위한 조건


OS : Windows 2000 이상만 지원합니다.

필요한 파일 : Shlwapi.h

필요한 라이브러리 : Shlwapi.lib

필요한 dll : Shlwapi.dll

 

< 예제 코드 >

#include <iostream>
#include <windows.h>
#include <shlwapi.h>

int main()
{
  WCHAR szPath[_MAX_PATH + 1] = L"C:\\Users\\Heungbae\\Desktop\\임시.txt";
  WCHAR szSource[_MAX_PATH + 1];

  wcsncpy_s(szSource, _MAX_PATH, szPath, _MAX_PATH-1 );

  PathRemoveFileSpecW(szSource);

  setlocale(LC_ALL, "");
  std::wcout << L"PathRemoveFileSpec : " << szSource << std::endl;

  getchar();
  return 0;
}


< 결과 >



< 초보자를 위해서... >

위에서 사용 조건 중

필요한 라이브러리 : Shlwapi.lib

라는 부분이 있는데 이것은 프로젝트 속성창에서 아래와 같이 추가합니다.




참고
MSDN : http://msdn.microsoft.com/en-us/library/bb773748%28VS.85%29.aspx




저작자 표시
신고
by 흥배 2010.09.29 09:00
| 1 |