336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
MFC애서 키입력을 처리할때 OnKeyDown message를 주로 사용하지만
OnKeyDown message의 경우 View 클래스에 우선권이 있기 때문에
MainFrm 클래스등에서 사용하려할때 원하는대로 사용되지 않는 경우가 있다

이럴때 PreTranslateMessage를 사용하면 된다

PreTranslateMessage는 메세지 처리 함수중 윈도우에 메세지가 전달되기 전에
미리 메세지를 알아내어 처리할수 있기때문이다

BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
   // TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
   if (pMsg->message == WM_KEYDOWN)
   {
      if (pMsg->wParam == VK_SPACE)

      ...

   }
   return CFrameWnd::PreTranslateMessage(pMsg);
}
이런식으로 사용하면 된다

'Programming > Windows programming' 카테고리의 다른 글

OpenCV MFC용 이미지 클래스  (0) 2009.07.16
하나의 에디트박스에 두개의 스핀컨트롤러 사용하기  (0) 2009.06.11
CFileDialog  (0) 2009.05.22
[VC++ 2003] File filter setting  (0) 2009.04.30
XML perser  (0) 2009.03.13
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

CFileDialog::CFileDialog

CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL );


Parameters

bOpenFileDialog : 파일 열기 대화상자를 생성하려면 TRUE로, 파일 저장하기 대화상자를 생성하려면 FALSE로 설정한다.

lpszDefExt : 디폴트 파일 확장자. 사용자가 파일명 에디트 박스에서 확장자를 포함하지 않으면, lpszDefExt에 설정된 확장자가 자동적으로 파일명에 붙는다. 인자가 NULL이면, 확장자가 붙지 않는다.

lpszFileName : 파일명 에디트 박스에 나타나는 초기 파일명. NULL이면, 초기에 파일명이 나타나지 않는다.

dwFlags : 사용자가 대화상자를 사용자 정의로 지정하도록 하는 하나 또는 그 이상의 플래그의 조합.

lpszFilter : 사용자가 파일에 적용할 수 있는 필터를 지정하는 문자열

pParentWnd : 파일 대화상자 객체의 부모 윈도우 또는 오우너 윈도우에 대한 포인터


Remarks

표준 윈도우 파일 대화상자 객체를 생성하기 위해서 이 함수를 호출한다. bOpenFileDialog의 값에 따라서 파일 열기 대화상자 또는 파일 저장하기 대화상자가 생성된다.

사용자가 다중 파일 선택을 가능하도록 하려면, DoMoal을 호출하기 전에 OFN_ALLOWMULTISELECT 플래그를 설정한다. 다중 파일명의 반환된 리스트를 처리하기 위해서 파일명 버퍼를 마련해야 한다. 이것은 m_ofn.lpstrFile을 할당한 버퍼에 대한 포인터로 대치함으로써 가능하다. CFileDialog를 생성한 수에 그러나 DoModal을 호출하기 전에 해야한다. 게다가, m_ofn.lpstrFile에 의해서 가리켜지는 버퍼에서 문자의 수를 m_ofn.nMaxFile에 설정해야 한다.

lpszFilter 인자가 파일명의 타입을 결정하는데 사용되어진다면 파일은 파일 리스트 박스에 표시되어야 한다. 문자열 쌍에서 첫 번째 문자열은 필터를 나타낸다. 두 번째 문자열은 사용되는 파일 확장자를 나타낸다. 다중 확장자는 구획문자 ‘;’를 사용해서 설정한다. 이 인자를 위해서 CString 객체를 사용할 수 있다. 문자열은 두 개의 ‘|’ 문자로 끝나고, 다음에 NULL이 온다.


CFileDialog::DoModal

virtual int DoModal( );


Return Value

함수가 성공적으로 수행되면, IDOK 또는 IDCANCEL 리턴. 대화상자에서 사용자가 선택한 버튼에 따라 IDOK 또는 IDCANCEL이 리턴된다.

IDCANCEL이 리턴되면, 에러가 발생했는지를 결정하기 위해서 윈도우즈 CommDlgExtendedError 함수를 호출할 수 있다.


Remarks

윈도우즈 공통 대화상자를 표시하고, 사용자가 파일과 디렉토리를 찾고, 파일명을 입력하도록 하기 위해서 이 함수를 호출한다.

m_ofn 구조체의 멤버들을 설정해서 다양한 파일 대화상자 옵션을 초기화하려면, 대화상자 객체가 생성되고, DoModal이 호출되기 전에 해야 한다.

사용자가 대화상자의 OK나 Cancel 버튼을 누르거나, 대화상자의 컨트롤 메뉴에서 Close 옵션을 선택했을 때, 컨트롤이 어플리케이션에 리턴된다. 그때서야 사용자가 대화상자에 입력한 정보나 설정을 알아내기 위해서 다른 멤버 함수들을 호출할 수 있다.

DoModal은 CDialog 클래스에서 오버라이딩된 가상함수이다.


CFileDialog::GetFolderPath

CString GetFolderPath() const;


Return Value

현재 열고있는 폴더나 디렉토리를 CString object에 담고있다

Remarks

이 다이얼로그 박스는 OFN_EXPLORER 스타일을 반드시 생성해야 한다.

CFileDialog::GetNextPathName

CString GetNextPathName (POSITION& pos) const;

Return Value

파일의 총 경로

Parameters
GetNextPathName 또는 GetStartPosition을 호출 되면 POSITION value를 리턴


Remarks

파일이름의 경로는 파일이름에 이렉토리 경로를 포함한다.
예를 들어, GetNextPathName 는 C:\FILES\TEXT.DAT 파일의 반환 값으로  "C:\FILES\TEXT.DAT"를 반환할 것이다. 만약 GetStartPosition을 사용하여 초기 위치를 설정한다면 GetNextPathName을 반복문 전에 사용하여야 한다.


CFileDialog::GetPathName

CString GetPathName( ) const;


Return Value

파일의 전체 경로를 리턴한다.


Remarks

대화상자에 입력된 파일의 전체 경로를 알아내기 위해서 이 함수를 호출한다. 예를 들면, GetPathName은 파일 C:\FILES\TEXT.DAT에 대해서 "C:\FILES\TEXT.DAT"를 리턴 할 것이다.

m_ofn.Flags가 OFN_ALLOWMULTISELECT 플래그 설정을 가지면, 이 문자열은 첫 번째 문자열은 선택된 파일 그룹의 디렉토리 경로이고, 그 다음은 사용자가 선택한 모든 파일명을 가지는 널종료 문자열을 포함한다. 이러한 이유로, 리스트에서 다음 파일명을 얻기 위해서 GetStartPosition과 GetNextPathName 멤버 함수를 사용한다.


CFileDialog::GetFileName

CString GetFileName( ) const;


Return Value

파일명을 리턴한다.


Remarks

대화상자에 입력된 파일명을 알아내기 위해서 이 함수를 호출한다. 물론 확장자도 포함된다. 예를 들면, GetFileName은 C:\FILES\TEXT.DAT에 대해서 "TEXT.DAT"을 리턴한다. 

m_ofn.Flages가 OFN_ALLOWMULTISELECT 플개그 설정을 가지면, 파일 경로명을 알아내기 위해서 GetStartPosition과 GetNextPathName을 호출해야 한다.


CFileDialog::GetOFN
const OPENFILENAME& GetOFN() const;

OPENFILENAME& GetOFN;

Return Value

OPENFILENAME 구조체


Remarks

이 함수는 FileOpen이나 File Save As 다이얼로그 박스를 DoModal 함수를 호출하기 이전에 두번째 버전을 사용하여 초기화한다.

예를 들어 m_ofn의 맴버 lpstrTitle를 이용해 다이얼로그 박스의 캡션을 설정할 수 있다.

CFileDialog::HideControl
void HideControl( int nID);

 

Parameters

nID, 컨트롤의 ID를 숨길 수있습니다


Remarks

다이얼로그 박스는 반드시 OFN_EXPLORER 스타일을 이용하여 생성해야 한다

 

CFileDialog::GetFileExt

CString GetFileExt( ) const;


Return Value

파일의 확장자


Remarks

대화상자에 입력된 파일의 확장자를 알아내기 위해서 이 함수를 호출한다. 예를 들어, 파일명이 DATA.TXT인 파일명이 입력되면, GetFileExt는 "TXT"를 리턴한다.

m_ofn.Flags가 OFN_ALLOWMULTISELECT 플래그 설정을 가지면, 이 문자열은 첫 번째 문자열은 선택된 파일 그룹의 디렉토리 경로이고, 그 다음은 사용자가 선택한 모든 파일명을 가지는 널종료 문자열을 포함한다. 파일 경로명을 얻기 위해서 GetStartPosition과 GetNextPathName 멤버 함수를 사용한다.


CFileDialog::GetFileTitle

CString GetFileTitle( ) const;


Return Value

파일의 타이틀


Remarks

대화상자에 입력된 파일의 이름을 알아내기 위해서 이 함수를 호출한다. 파일의 이름은 확장자나 경로없이 그것의 이름만을 포함한다. 예를 들면, GetFileTitle은 C:\FILES\TEXT.DAT에 대해서 "TEXT"를 리턴한다.

m_ofn.Flags가 OFN_ALLOWMULTISELECT 플래그 설정을 가지면, 이 문자열은 첫 번째 문자열은 선택된 파일 그룹의 디렉토리 경로이고, 그 다음은 사용자가 선택한 모든 파일명을 가지는 널종료 문자열을 포함한다. 이러한 이유로, 리스트에서 다음 파일명을 얻기 위해서 GetStartPosition과 GetNextPathName 멤버 함수를 사용한다.


CFileDialog::GetReadOnlyPref

BOOL GetReadOnlyPref( ) const;


Return Value

대화상자에서 읽기 전용 체크박스가 선택되면, 0이 아닌 값을 그렇지 않으면 0을 리턴.


Remarks

윈도우즈 표준 파일 열기 대화상자에는 읽기 전용 체크 박스가 있다. 이 함수는 읽기 전용체크 박스가 체크되었는지를 결정하기 위해서 이 함수를 호출한다. 읽기 전용 체크 박스는 CFileDialog 생성자에서 OFN_HIDEREADONLY 속성을 설정하면 보이지 않게 할 수 있다.


CFileDialog::GetStartPosition

POSITION GetStartPosition( ) const;


Return Value

순환을 위한 위치값으로 리스트가 비어있으면 NULL을 리턴.


Remarks

m_ofn.Flags가 OFN_ALLOWMULTISELECT 플래그 설정을 가질 경우, 리스트에 있는 첫 번째 파일 경로명의 위치를 알아내기 위해서 이 멤버 함수를 호출한다.


CFileDialog::OnShareViolation

virtual UINT OnShareViolation( LPCTSTR lpszPathName );


Return Value

다음 값들 중 하나를 리턴:

OFN_SHAREFALLTHROUGH : 대화상자로부터 리턴된 파일명

OFN_SHARENOWARN : 처리할 필요가 있는 액션이 더 이상 없음

OFN_SHAREWARN : 에러에 대한 표준 경고 메시지를 검색


Parameters

lpszPahtName : 공유 위반이 발생한 파일의 경로


Remarks

공유 위반의 사용자 정의 처리를 제공하기 위해서 이 함수를 오버라이딩 한다. 보통, 이 함수를 사용할 필요가 없다. 왜냐하면, 프레임워크가 공유 위반의 디폴트 체크를 제공하고, 공유 위반이 발생하면, 메시지 박스를 보여주기 때문이다. 

공유 위반 확인을 불가능하게 하려면, m_ofn.Flags를 가진 플래그 OFN_SHAREAWARE를 조합한 OR 연산자를 사용한다.


CFileDialog::OnFileNameOK

virtual BOOL OnFileNameOK( );


Return Value

파일명이 유효한 이름이 아니면 1을 그렇지 않으면 0을 리턴.


Remarks

공통 파일 대화상자에 입력된 파일명의 사용자 유효성 검사를 제공하기를 원하는 경우만 이 함수를 오버라이딩한다. 이 함수는 어떤 어플리케이션 지정 이유로 파일명을 거절하도록 한다. 보통은, 이 함수를 사용할 필요가 없다. 왜냐하면, 프레임워크는 파일명의 디폴트 유효성 검사를 제공하고, 무효한 파일명이 입력된다면 메시지 박스를 출력하기 때문이다.

1이 리턴되면, 대화상자는 사용자가 다른 파일명을 입력하도록 하기 위해서 표시된 상태로 그대로 있는다. 대화 프로시저는 리턴 값이 0이면 대화상자를 없앤다. 다른 0이 아닌 리턴된 값들은 저장되어지고 사용되지는 않는다.


CFileDialog::OnLBSelChangedNotify

virtual void OnLBSelChangedNotify( UINT nIDBox, UINT iCurSel, UINT nCode);


Parameters

nIDBox : 선택된 리스트 박스나 콤보 박스의 ID

iCurSel : 현재 선택된 인덱스

nCode : 컨트롤 통지 코드. 이 인자는 다음 값들중 하나를 가져야만 한다.

CD_LBSELCHANGE : 단일 선택 리스트 박스에서 선택된 아이템인 iCurSel을 지정한다. 

CD_LBSELSUB : 다중 선택 리스트 박스에서 더 이상 선택된 것이 없다는 iCurSel을 지정한다.

CD_LBSELADD   Specifies that iCurSel is selected in a multiselection list box.

: 다중 선택 리스트 박스에서 선택된 iCurSel을 지정한다.

CD_LBSELNOITEMS   Specifies that no selection exists in a multiselection list box.

: 다중선택 리스트 박스에서 선택된 것이 더 이상 없다는 것을 지정한다.


Remarks

이 함수는 리스트 박스에서 현재 선택된 것이 바뀔려고 할 때마다 호출된다.  리스트 박스에서 선택의 변화를 처리하기 위해서 사용자 정의로 하려면 이 함수를 오버라이딩 한다.


CFileDialog::OnInitDone

virtual void OnInitDone( );


Remarks

WM_NOTIFY CDN_INITDONE 메시지를 처리하기 위해서 이 함수를 오버라이딩 한다. 통지 메시지는 시스템이 차일드 대화상자의 컨드롤들을 위한 공간을 만들기 위해서 열기나 저장하기 대화상자에서 컨트롤들을 배치하는 것을 마쳤을 때 보내진다.

통지는 OFN_EXPLORER 속성을 가지고 생성된 대화화상자에게만 보내진다. OFN_EXPLORER 속성에 대해서 알고싶으면, OPENFILENAME 구조체와 열기와 저장하기 대화상자를 참조하라.


CFileDialog::OnFileNameChange

virtual void OnFileNameChange( );


Remarks

WM_NOTIFY CDN_SELCHANGE 메시지를 처리하기 위해서 이 함수를 오버라이딩 한다.

Notification is sent only if the dialog box was created with the OFN_EXPLORER style. 통지는 OFN_EXPLORER 속성을 가지고 생성된 대화상자에게만 보내진다. 통지에 대해서 더 알고싶으면, CDN_SELCHANGE를 참조하시오. 통지는 OFN_EXPLORER 속성을 가지고 생성된 대화화상자에게만 보내진다. OFN_EXPLORER 속성에 대해서 알고싶으면, OPENFILENAME 구조체와 열기와 저장하기 대화상자를 참조하라.


CFileDialog::OnFolderChange

virtual void OnFolderChange( );


Remarks

WM_NOTIFY CDN_FOLDERCHANGE 메시지를 처리하기 위해서 이 함수를 오버라이딩 한다. 통지 메시지는 새로운 폴더가 열기 또는 저장하기 대화상자에서 열릴 때 보내진다.

통지는 OFN_EXPLORER 속성을 가지고 생성된 대화화상자에게만 보내진다. 통지에 대해서 더 알고싶으면, CDN_FOLDERCHANGE를 참조하시오. OFN_EXPLORER 속성에 대해서 알고싶으면, OPENFILENAME 구조체와 열기와 저장하기 대화상자를 참조하라.


CFileDialog::OnTypeChange

virtual void OnInitDone( );


Remarks

WM_NOTIFY CDN_TYPECHANGE 메시지를 처리하기 위해서 이 함수를 오버라이딩 한다. 통지 메시지는 사용자가 열기 또는 저장하기 대화상자에서 파일 타입의 리스트에서 새로운 파일 타입을 선택할 때 보내진다.

통지 메시지는 OFN_EXPLORER 속성을 가지고 생성된 대화상자에게만 보내진다.  통지 메시지에 대해서 더 알고싶으면, CDN_TYPECHANGE를 참도하시오. OFN_EXPLORER 속성에 대해서 더 알고싶으면, OPENFILENAME 구조체와 열기와 저장하기 대화상자를 참조하시오.

'Programming > Windows programming' 카테고리의 다른 글

OpenCV MFC용 이미지 클래스  (0) 2009.07.16
하나의 에디트박스에 두개의 스핀컨트롤러 사용하기  (0) 2009.06.11
PreTranslateMessage  (0) 2009.05.29
[VC++ 2003] File filter setting  (0) 2009.04.30
XML perser  (0) 2009.03.13
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

쓰레드가 2개 이상 실행될 때 여러가지 변수 가있습니다.

하나의 공유자원(예를들어 동시에 접근하는 변수) 에 접근할 때, 파일 입출력 이나 디바이스I/O작업을 할 때 동기화 오브젝트가 필요합니다.

동기화 오브젝트 없이 쓰레드가 공유 자원을 사용할 때 공유자원이 원치 않은 값이 될수 있고, I/O작업 시 쓰레드가 I/O작업이 끝날 때 까지 무한정 블로킹(blocking : 특정 함수가 리턴 될 때 까지 기다림)현상이 발생할 수 있습니다.

동기화 오브젝트를 사용하여 다중 쓰레드에서 어떻게 안전 하게 공유자원에 접근하고 다른 쓰레드간의 실행 순서등을 조작하는지에 대해 알아 보겠습니다.

 동기화 오브젝트는 유저 모드와 커널 모드로 분류할 수 있습니다.

 

유저 모드

 유저 모드는 현재 프로세스/쓰레드 내의 상태를 말합니다.

유저모드에서는 커널 오브젝트(프로세스, 파일, 디바이스 등)으로 바로 접근을 할 수 없고, 커널 오브젝트로 접근 시 시스템에 의해 변환 작업이 이루어집니다.

이런 변환 작업은 시간을 많이 걸리는 작업이기 때문에 유저 모드가 커널 모드 보다 속도가 빠릅니다.

유저 모드 동기화 방법은 코드레벨에서 동기화 하는 방법을 이야기 합니다.

유저모드에서 동기화는 사용하기 쉽고 커널 모드 동기화 함수들에 비해 속도가 빠른 장점이 있지만 커널 오브젝트(파일 I/O, 프로세스, 쓰레드 등)의 동기화는 불가능하다는 단점이 있습니다.

 Interlocked

 Interlocked 함수들은 다중 쓰레드에서 공유변수들을 안전하게 1씩 증가/감소, 특정값을 증가 , 비트 연산을 할 수 있습니다.

Intlocked 함수는 사용하기 쉬우므로 길게 설명은 하지 않겠습니다.

아래 사이트를 참조하시길 바랍니다.

http://msdn2.microsoft.com/en-us/library/ms686360(VS.85).aspx

 

 

크리티컬 섹션(CRITICAL SECTION)

 

크리티컬 섹션은 특정 코드영역을 쓰레드가 동시에 실행되는 것을 막아 줍니다.

아래는 크리티컬 섹션 관련 함수들입니다.

DeleteCriticalSection

크리티컬 섹션 오브젝트를 삭제 합니다.

EnterCriticalSection

특정 크리티컬 섹션권한을 가질 까지 기다립니다.(Wait)

InitializeCriticalSection

크리티컬 섹션 오브젝트를 초기화 합니다.

InitializeCriticalSectionAndSpinCount

크리티컬 섹션 오브젝트를 초기화 하고 스핀 카운트를 설정합니다.

InitializeCriticalSectionEx

크리티컬 섹션을 초기화하고 스핀카운트 설정, 부가기능을 설정합니다.

LeaveCriticalSection

크리티컬 섹션 오브젝트 권한을 해제합니다..

SetCriticalSectionSpinCount

특정 크리티컬 섹션 오브젝트 스핀카운트를 설정합니다.

TryEnterCriticalSection

블로킹(Wait) 되지 않고 크리티컬 섹션 오브젝트의 권한을 요청합니다.

InitializeCriticalSectionAndSpinCount 함수는 스핀 카운트를 두어서 쓰레드가 크리티컬 섹션 오브젝트를 획득하지 못하면 Wait상태로 일정 시간(스핀카운트) 루프를 돌아 크리티컬 섹션오브젝트가 해제 되었는지 체크합니다.

해제되지 않았으면 Sleep하게 됩니다.

이 함수는 멀티 프로세서 환경에서만 유효하며, 스핀카운터는 4000을 추천(Windows Via C/C++)하지만 자신의 환경에서 값을 바꾸어 가며 테스트 해보길 권장합니다.

 

#include <Windows.h>

CRITICAL_SECTION g_cs;

 

//크리티컬 섹션 오브젝트를 초기화 합니다.

void InitCriticalSection()

{

        InitializeCriticalSection(&g_cs);

}

 

unsigned _stdcall CallThreadHandlerProc(void *pThreadHandler)

{

        while (bExit == FALSE)

        {

               if(TryEnterCriticalSection(&g_cs))

               {

                       //쓰레드 작업을 수행 합니다.

                       //수행 하고 LeaveCriticalSection 함수를 호출

                       //하여 크리티컬섹션 오브젝트를 해제합니다.

 

                       LeaveCriticalSection(&g_cs);

               }

               else

               {

                        //크리티컬 섹션 오브젝트 획득에 실패시 수행할

                        // 작업을 선언합니다.

                        //SwitchToThread함수를 호출하여 다른 쓰레드로

                        // 스위칭 합니다.

                       SwitchToThread();                    

               }             

        }

        DWORD exitCode;

        GetExitCodeThread(InputThrd, &exitCode);

        _endthreadex(exitCode);

        return 0;

}

**Sleep() 함수와 SwitchToThread()함수는 디스패쳐가 다른 쓰레드로 스케쥴 하도록 합니다.

차이점은 Sleep()함수는 현재 쓰레드보다 우선순위가 같거나 높은 쓰레드가 없으면 쓰레드 전체를 리스케쥴링(rescheduling)합니다.

 

 

Slim Reader/Writer Locks

Slim reader/writer (SRW) locks 하나의 프로세스내의 쓰레드들이 공유자원을 동기화 할수 있습니다.

아주 작은 메모리를 차지하면서 속도도 빠릅니다.

Reader 쓰레드는 공유자원을 읽고 Writer 쓰레드는 공유자원에 쓰기 작업을 할수 있습니다.

다중 쓰레드가 공유자원을 읽고 쓰기를 , 크리티컬 섹션과 뮤텍스 같은 상호배제 오브젝트(exclusive locks)들은 reader 쓰레드는 계속 돌고 writer 쓰레드는 거의 돌지 못하면 병목현상(bottle neck) 발생 있습니다.

SRW locks 공유자원에 접근 할수 있는 두가지 모드를 제공합니다. :

·         Shared mode : 읽는 작업을 하는 쓰레드가 여러 개일 공유자원을 읽기 전용으로 접근할 있도록 해서 동시 다발적으로 작업을 할수 있도록 합니다.  만약 읽는 작업이 쓰는 작업을 초과 경우, 성능과 처리량은 크리티컬 섹션과 동일하게 됩니다.

·         Exclusive mode : 읽기/쓰기 쓰레드는 하나의 쓰레드만 접근 있습니다. Exclusive mode 락이 걸려지면 다른 쓰레드들은 공유자원에 접근할 없습니다.

하나의 SRW lock 두가지 모드를 동시에 가질수 있습니다. 읽는 쓰레드는 Shared mode 쓰는 쓰레드는 Exclusive mode 작업을 있습니다.  어떤 쓰레드가 소유권을 먼저 가질지는 알수 없습니다. SRW Locks 공정하거나 선입선출(First In First Out : FIFO)방식이 아닙니다.

SRW lock 포인터 크기를 가집니다. 장점은 속도가 빠르고 lock상태의 변환이 빠르다는 입니다.

단점은 아주 작은 상태 정보만 저장이 되어 재귀적으로 SRW locks 가질 없습니다. Shared Mode 쓰레드가 Shred Mode 변환 될수 없습니다.

SWR Locks Windows Server 2008,Vista 에서만 사용이 가능합니다.

아래는 SRW lock 함수들 입니다.

SRW lock function

Description

AcquireSRWLockExclusive

SRW lock  exclusive mode 얻습니다.

AcquireSRWLockShared

SRW lock shared mode 얻습니다.

InitializeSRWLock

SRW lock 초기화 합니다.

ReleaseSRWLockExclusive

exclusive mode SRW lock 해제 합니다.

ReleaseSRWLockShared

shared mode SRW lock 해제 합니다.

SleepConditionVariableSRW

SRW작업이 완료 될때까지 Sleep 합니다.

 

커널 모드

유저 모드에서 커널 오브젝트에 접근을 할 때 시스템은 커널 모드로 변환을 합니다.

커널 오브젝트에는 File, Event, Mutex, Semaphore, Process, Waitable Timer, Job, Thread 가 있습니다.

커널 모드에서 동기화는 커널 오브젝트가 non-Signal인지 Signal 상태인지를 보고 쓰레드를 스케쥴링합니다.

커널 오브젝트가 signal상태이면 쓰레드가 돌아갈 준비가 된 상태이고, non-signal 상태이면 쓰레드는 기다림(Wait)상태 입니다.

 

 

이벤트(EVENT)

가장 많이 보편화되고 많이 쓰는 다중 쓰레드 동기화 오브젝트가 이벤트가 아닌가 생각이 됩니다.

이벤트로 다중 쓰레드 동기화 하는 방법에는 두가지 방법이 있습니다.

개발자가 직접 이벤트를 수동으로 signal/non-signal 상태로 변환 하는 것과 시스템이 자동으로 이벤트를 signal/non-signal상태로 변환 하는 방법입니다.

이벤트를 기다리는 방법은 WaitForSingleObjec/WaitForSingleObject 함수를 사용합니다. 이벤트가 non-signal상태가 될 때까지 쓰레드는 Wait상태로 됩니다.

이벤트 및 모든 커널 오브젝트는 사용이 끝나면 CloseHandle로 사용을 종료 해야 합니다.

Event function

Description

CreateEvent

이벤트 오브젝트를 생성하거나 오픈 합니다.

CreateEventEx

이벤트 오브젝트를 생성하거나 오픈 합니다.(접근 권한을 줄수 있습니다.)

OpenEvent

존재하는 이름이 있는 이벤트 오브젝트를 오픈 합니다.

PulseEvent

특정 이벤트 오브젝트를 signal 상태로 바꾸고 일정시간 non-signal상태로 바끕니다.

ResetEvent

이벤트 오브젝트를 non-signal 상태로 놓습니다.        

SetEvent

이벤트 오브젝트를 signal 상태로 놓습니다.          

 

간단 하게 SDI 프로그램에서 수동 모드(passive mode) 이벤트를 이용하여 사각형과 원을 그리는 멀트 쓰레드 프로그램을 보겠습니다.

 

BOOL CEventSampleView::PreCreateWindow(CREATESTRUCT& cs)

{

        // TODO: CREATESTRUCT cs를수정하여여기에서

        //  Window 클래스또는스타일을수정합니다.

        srand( (unsigned)time( NULL ) );

 

        //종료조건을초기화합니다.

        m_bContinue = TRUE;

        //수동모드이벤트오브젝트를생성합니다.

        m_DrawEvent = CreateEvent(0, TRUE, TRUE, _T("DrawEvent"));

 

        //시그널상태로둡니다.

        SetEvent(m_DrawEvent);

       

        return CView::PreCreateWindow(cs);

}

 

/*OnDraw 메시지 핸들러에서 사각형을 그리는 쓰레드와

원을 그리는 쓰레드를 생성합니다.*/

void CEventSampleView::OnDraw(CDC* /*pDC*/)

{

        CEventSampleDoc* pDoc = GetDocument();

        ASSERT_VALID(pDoc);

        if (!pDoc)

               return;

        m_RectThrd = AfxBeginThread(RectThreadProc,reinterpret_cast<LPVOID>(this));

        m_CricleThrd = AfxBeginThread(CircleThreadProc, reinterpret_cast<LPVOID>(this));

        // TODO: 여기에원시데이터에대한그리기코드를추가합니다.

}

 

/*사각형을 그리는 쓰레드 프로시져*/

UINT CEventSampleView::RectThreadProc(__in LPVOID lpParameter)

{

        CEventSampleView* pView = reinterpret_cast<CEventSampleView*>(lpParameter);

        int x=0,y=0, cx=0, cy=0;

        cx = 100;

        cy = 100;

        while(pView->m_bContinue)

        {

               //시그널상태가될때까지기다립니다.

               WaitForSingleObject(pView->m_DrawEvent, INFINITE);

               //이벤트오브젝트를받아오면넌시그널상태로둡니다.

               ResetEvent(pView->m_DrawEvent);

              

               HDC hDC = ::GetDC(pView->GetSafeHwnd());

               x= rand()%300;

               y = rand()%300;

               ::Rectangle(hDC,x, y, x+cx, y+cy);

               ::ReleaseDC(pView->GetSafeHwnd(),hDC);

               //작업이끝나면이벤트를시그널상태로두어다음쓰레드가가질수

               //있도록합니다.

               SetEvent(pView->m_DrawEvent);

        }

        DWORD dCode=0;

        GetExitCodeThread(pView->m_CricleThrd->m_hThread, &dCode);

        AfxEndThread(dCode, TRUE);

        return 0;

}

 

/*원을 그리는 쓰레드 프로시져*/

UINT CEventSampleView::CircleThreadProc(__in LPVOID lpParameter)

{

        CEventSampleView* pView = reinterpret_cast<CEventSampleView*>(lpParameter);

        int x=0,y=0, cx=0, cy=0;

        cx = 100;

        cy = 100;

        while(pView->m_bContinue)

        {

               WaitForSingleObject(pView->m_DrawEvent, INFINITE);

               ResetEvent(pView->m_DrawEvent);

               HDC hDC = ::GetDC(pView->GetSafeHwnd());

               x= rand()%300;

               y = rand()%300;

               ::Ellipse(hDC,x, y, x+cx, y+cy);

               ::ReleaseDC(pView->GetSafeHwnd(),hDC);

               SetEvent(pView->m_DrawEvent);

        }

        DWORD dCode=0;

        GetExitCodeThread(pView->m_CricleThrd->m_hThread, &dCode);

        AfxEndThread(dCode, TRUE);

        return 0;

}

 

//프로그램이 종료할 때 종료조건을 맞춰 주고 쓰레드 종료 메시지를 주어 정상적으로

//종료하도록 하고, 이벤트 핸들을 닫습니다.

void CEventSampleView::OnDestroy()

{

        CView::OnDestroy();

        m_bContinue = FALSE;

        DWORD dExitCode = 0;

        GetExitCodeThread(m_CricleThrd->m_hThread,&dExitCode);

        PostQuitMessage(dExitCode);

 

        GetExitCodeThread(m_RectThrd->m_hThread,&dExitCode);

        PostQuitMessage(dExitCode);

 

        CloseHandle(m_DrawEvent);

}

 

 

뮤텍스(MUTEX)

뮤텍스는 하나의 공유자원에 대한 상호 배타(mutual exclusive)적으로 동기화 하는 방법입니다.  뮤텍스는 서로 다른 프로세스의 쓰레드의 동기화를 할수 있습니다.  이 특성을 이용해서 보통 하나 이상의 프로그램을 실행하기 위해 뮤텍스를 이용합니다.(이걸 깨는 방법도 있죠.)

뮤텍스는 다음과 같은 규칙이 있습니다.

 

Ø  쓰레드의 ID 0(유효하지 않은 쓰레드 ID)이면 뮤텍스의 소유권은 어느 쓰레드에게도 없다는 의미 이고 뮤텍스 오브젝트는 시그널된 상태입니다.

Ø  쓰레드 ID 0이 아닌 값이면, 해당쓰레드(생성 시킨 쓰레드)가 소유권을 가지면 뮤텍스 오브젝트는 non-signal상태 입니다.

Ø  다른 커널 오브젝트와는 달리 뮤텍스는 소유권(thread ownership)이라는 개념이 있습니다. 

뮤텍스를 해제할 때(ReleaseMutex), 쓰레드 ID와 생성할 때 설정한 쓰레드의 ID가 맞지 않으면 해제에 실패하고 시스템은 해당 뮤텍스의 시그널 상태를 기다리는 다른 쓰레드를 스케쥴링 합니다.

뮤텍스의 소유권을 가진 쓰레드가 뮤텍스를 해제 하지 않고 종료 되면, 시스템은 해당 뮤텍스를 “abandoned”상태로 두고, 이 뮤텍스를 기다리는 쓰레드를 찾아 기다리고 있는 쓰레드에 뮤텍스의 소유권을 주고 해당 쓰레드를 스케쥴링 합니다.

Mutex function

Description

CreateMutex

뮤텍스 오브젝트를 생성하거나 오픈 합니다.

CreateMutexEx

뮤텍스 오브젝트를 생성하거나 오픈합니다. 접근 권한 속성을 있습니다.

OpenMutex

이름이 있는 뮤텍스 오브젝트를 오픈 합니다.

ReleaseMutex

뮤텍스 오브젝트를 해제합니다.

 

http://msdn2.microsoft.com/en-us/library/ms686927(VS.85).aspx

 

 

세마포어(SEMAPHORE)

세마포어는 공유 자원의 카운팅의 용도로 사용합니다.

세마포어는 사용 개수(usage count)이외에 signed 32비트 값 2개를 더 가지고 있습니다.

Ø  최대 리소스 카운트(maximum resource count) : 세마포어가 관리할 수 있는 최대 리소스의 개수.

Ø  현재 리소스 카운트(current resource count) : 현재 사용 가능한 리소스의 개수.

세마포어는 다음과 같은 규칙을 가지고 동작을 합니다.

Ø  현재 리소스 카운터가 0보다 크면(>0) 세마포어 오브젝트는 signal 상태입니다.

Ø  현재 리소스 카운터가 0이면, 세마포어 오브젝트는 non-signal상태입니다. 

Ø  시스템은 현재 리소스카운터를 값이 되지 않도록 합니다.

Ø  현재 리소스 카운터는 최대 리소스 카운터 보다 클 수 없습니다.

Semaphore function

Description

CreateSemaphore

세마포어를 생성/오픈 합니다.

CreateSemaphoreEx

세마포어를 생성/오픈 합니다. 접근 권한을 있습니다.

OpenSemaphore

이름이 있는 세마포어 오브젝트를 오픈합니다.

ReleaseSemaphore

사용 가능한 리소스 개수를 증가 시킵니다..

 

세마포어 사용 예는 아래 사이트를 참조 하세요.

http://msdn2.microsoft.com/en-us/library/ms686946(VS.85).aspx

 

 

Waitable Timer

Waitable Timer 오브젝트는 특정 시간이 되면 오브젝트가 시드널 됩니다.

특정 시간 마다 어떤 동작을 해야할 때 사용할 수 있습니다.

Waitable-timer function

Description

CancelWaitableTimer

Waitable Timer 오브젝트를 비활성화 시킵니다.

CreateWaitableTimer

Waitable Timer 생성하거나 오픈 합니다.

CreateWaitableTimerEx

Waitable Timer 생성/오픈 합니다.

OpenWaitableTimer

이름이 붙여진 Waitable Timer 오브젝트를 오픈 합니다.

SetWaitableTimer

Waitable Timer 오브젝트를 활성화 시키거나, Waitable Timer 오브젝트가 시그널 되었을 완료 통보 프로시져를 등록 있습니다..

TimerAPCProc

SetWaitableTimer 함수로 등로한 완료 통보 프로시져 선언.

 

 

Timer-queue Timer

Timer queue Timer 오브 젝트는 일정시간이 지나면 시그널되는 동작은 Waitable Timer 와 같습니다.

Timer Queue Timer 오브젝트는 일정 시간이 지나면 시그널 되는 오브젝트이고, Timer Queue오브젝트가 Timer Queue Timer 오브젝트를 큐 형태로 관리하면서

해당 프로 시져를 호출 합니다.

위의 그림은 Timer Queue오브젝트가 Timer Queue Timer 오브젝트를 관리하고,

Timer Queue Timer가 시그널 되면 해당 프로시져를 호출하는 모습입니다.

Timer-queue timer function

Description

ChangeTimerQueueTimer

Timer queue timer 오브젝트의 속성을 변경 합니다..

CreateTimerQueue

Timer Queue 오브젝트를 생성합니다.

CreateTimerQueueTimer

Timer Queue Timer 오브젝트를 생성합니다.

DeleteTimerQueue

타이머 오브젝트를 삭제 합니다.

DeleteTimerQueueEx

타이머 오브젝트를 삭제 합니다.

DeleteTimerQueueTimer

Timer Queue 있는 Timer Queue Timer 오브젝트를 삭제 합니다.

 

 

 

쓰레드간 통신

 마지막으로 쓰레드간 통신 하는 방법을 알아 보겠습니다.

윈도우 프로그래밍을 하면 윈도우에 SendMessage/PostMessage 함수로 메시지를 보내 듯이 쓰레드에 메시지를 보내고 받으면서 쓰레드간 통신을 할 수 있습니다.

쓰레드에 메시지를 보내는 함수는 PostThreadMessage 입니다.

BOOL PostThreadMessage(      
    DWORD idThread,  
/*해당 쓰레드 ID*/

    UINT Msg,       /*메시지 ID*/

    WPARAM wParam,    /*메시지를 받는 쓰레드로 넘겨주는 WPARAM 인자*/

    LPARAM lParam     /* 메시지를 받는 쓰레드로 넘겨주는 LPARAM 인자*/

);

 

PostThread로 보낸 메시지는 쓰레드 프로시져에서 PeekMessage/GetMessage로 받을 수 있습니다.

http://msdn2.microsoft.com/en-us/library/ms644936(VS.85).aspx

BOOL GetMessage(      
    LPMSG lpMsg,          
//MSG 구조체의 포인터 타입

    HWND hWnd,             //윈도우 핸들

    UINT wMsgFilterMin,    //필터링할 최소 메시지 ID

    UINT wMsgFilterMax     //필터링할 최대 메시지 ID

);

 

http://msdn2.microsoft.com/en-us/library/ms644943.aspx

 

BOOL PeekMessage(      
    LPMSG lpMsg,          
//MSG 구조체의 포인터 타입

    HWND hWnd,             //윈도우 핸들

    UINT wMsgFilterMin,    //필터링할 최소 메시지 ID

    UINT wMsgFilterMax,    //필터링할 최대 메시지 ID

    UINT wRemoveMsg        //메시지 큐에 해당 메시지를 지울지 안지울지 설정

);

 

PeekMessageGetMessage의 차이점은, GetMessage는 메시지가 메시지 큐에 들어 올때가지 블록되고 Peek메시지는 메시지가 없으면 FALSE를 리턴 합니다.

더 자세한 사항은 차고 사이트를 참고 하세요.

 

아래 예제 코드는 쓰레드 프로시져에서 메시지를 확인하고, 다른 작업을 수행 하는 예제 코드입니다.

 

unsigned _stdcall CallThreadHandlerProc(void *pThreadHandler)

{

        while (bExit == FALSE)

        {

               MSG msg;

             BOOL res = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);

             if (res)

             {

                        //0x404메세지 가 들어오면 특정 작업 수행

                    if (msg.message = 0x404)

                    {                  

                           std::cout<<"Message Received"<<std::endl;

                    }

             }

 

               //다른 작업 수행

        }

        DWORD exitCode;

        GetExitCodeThread(InputThrd, &exitCode);

        _endthreadex(exitCode);

        return 0;

}

………………………………………….

//다른 쓰레드에서 쓰레드에 메시지를 보냅니다.

BOOL res = PostThreadMessage(ID1, 0x00404, 0,0 );

 

참고 사이트 및 서적

Windows Via C/C++

http://msdn2.microsoft.com/en-us/library/aa904937(VS.85).aspx

http://windows-programming.suite101.com/article.cfm/win32_message_processing_primer

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

작년 대회때는 보드때문에 모바일과제를 지원했지만
이번 대회땐 지능형 휴머노이드를 지원할예정
안그래도 회사일이 많이 바쁜데 과연 시거할 시간이 날지는 의문...


자세한 사항은 eswcontest.com

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.


VC++ 6.0으로 날림 공부한지 얼마 안돼서 2003을 써먹을라니

공부할때와는 또 다른 부분들이 제법 보인다

그중하나가 파일 열기/저장에 관한 문제였는데

파일 필터를 사용하기위해 ID_FILE_SAVE등의 이벤트를 사용하여

파일 확장자 필터를 만들게 되면

타이틀바에 표시된 (title) - untitled 에서 untitled가 변경되지 않는

문제가 발생한다..

몇시간 고민끝에 구글신님의 도움을 받아 알아낸 정말 간단한 방법...

Resource view 에서 String Table중 IDR_MAINFRAME 을 이용하면 된다!

IDR_MAINFRAME 을 보면

(Title)\n\n(Title)\n\n\n(title).Document\n(title).Document

이런 식을로 되어있을 것있는 부분을 다음과 같이 변경하면 된다

(Title)\n\n(Title)\n My program File (*.dat)\n.dat\n(title).Document\n(title).Document

이때 파일 확장자가 여러가지를 설정할 경우에는 ';(세미콜론)'을 사용하여 구분지어주면 된다

'Programming > Windows programming' 카테고리의 다른 글

OpenCV MFC용 이미지 클래스  (0) 2009.07.16
하나의 에디트박스에 두개의 스핀컨트롤러 사용하기  (0) 2009.06.11
PreTranslateMessage  (0) 2009.05.29
CFileDialog  (0) 2009.05.22
XML perser  (0) 2009.03.13
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

학교 다닐때 배우면서 이걸 내가 과연 써먹을일이 있을까 싶어
완전 천대했던 XML을 써먹어야 하는 지못미 상황이...

머리가 어찌나 좋은지
용어고뭐고 그나마 당장 어렴풋이 생각나는건
어떤 형식으로 생겨먹었는지 밖에...

하늘이 무너져도 솟아날 구멍은 있다고
다행이 XML강좌를 하는 사이트를 찾아냈다는 사실ㅋㅋ

바로 요기

그리고 보너스!! C/C++에서 읽기용 파서로 쓸만한녀석
Small, simple, cross-platform, free and fast  C++ XML Parser



336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

요녀석은 데스크탑용(2008 공개 SW 공모대전 출품)


이녀석은 PXA270보드에 포팅한녀석(제6회 대한민국 임베디드 소프트웨어 공모대전 모바일부분 출품)


ARToolKit과 openGL 그리고 SDL을 이용한 프로젝트

내가 주로 한일은 보드관련해서 거의 포팅에 관한 일이었다

ARToolKit, Mesa Lib(OpenGL), GLUT 등을 컴파일및 최적화하는일과

최초에 데스크탑용으로 완성된 소스를 보드로 이식하는 일이었다

보드에 붙어있는 3D가속칩 드라이버가 제공되지 않는 관계로

데스탑에서 실행시키는 것 만큼의 퍼포먼스가 나오지 않는건 당연지사

때문에 영상처리 부분을 배재하고 터치스크린과 가속도센서로 대체하여

퍼포먼스를 끌어올림과 동시에 핸드헬드기기에서의 편의성을 상승시켰음
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.


이 두 녀석들 때문에 행복했던 11월

덕분에 지금 내 위치에선 만나기 힘든 사람들도 제법 만나면서

좀더 높은곳을 바라볼 수 있게 되었고

조금더 성장 할 수 있는 계기가 되었다

....



하지만 취업에 있어서는 토익점수 700보다

소용없는 두 녀석들ㅋㅋㅋ

그래도 이녀석들로인해 조금이나마 가능성을 보게된것이

아마도 가장큰 수확이 아닐까 싶다!!

'끄적임' 카테고리의 다른 글

중기정 과제 발표일!  (1) 2009.06.22
Nike + iPod Sport Kit  (1) 2009.06.02
2008 공개 SW 공모대전 대상받던날  (0) 2008.12.11
비트컴튜터 사보에 실릴 우리팀 사진  (1) 2008.11.18
Going to San Francisco  (1) 2008.11.09
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

시상을 위해 소프트웨어 산업인의날 행사 에 참여하게 되었다

태어나 처음으로 호텔에서 가져본 행사라 다소 떨리고 긴장되었지만

한편으로 이런곳에 참석도한다는게 무척 기분이 좋왔다ㅋㅋ


 행사장 모습으로 중요참석자나 대표로 시상하는 사람은 지정석에 앉았지만

그외 사람은 그외자리에 앉으라길래 아무곳이나 앉았다


테이블은 위사진처럼 세팅되어있었다

한번도 먹어보지 못한 스테이크 정식을 호텔에서 먹게된다는 사실이 너무 기대 되었다ㅋㅋ


요건 먹게될 음식의 메뉴들...

개회사와 연설등등이 끝나고 드디어 시상식이 시작되었다.


상받으려 대기중인 우리팀장 원준이형

긴장하고 있는 모습이 역력했다.ㅋㅋ

시상식이 끝나고 드뎌 기다리던 만찬시간!!

그리고 맛나게 먹은 음식들...


그리고 만찬간에 흥을 돋아준 벤드 공연


그리고 이후에 이루에진 기념 촬영ㅋㅋㅋ


그리고 같이온 친구 정민이와 한컷ㅋㅋ

참고로 필카라 화벨조절이 안됨

'끄적임' 카테고리의 다른 글

Nike + iPod Sport Kit  (1) 2009.06.02
영광의 11월  (0) 2008.12.12
비트컴튜터 사보에 실릴 우리팀 사진  (1) 2008.11.18
Going to San Francisco  (1) 2008.11.09
100달러 지폐의 가치 -좋은생각 中...  (0) 2008.05.26
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.


이번에 코엑스 인터콘티넨탈 호텔에갔을때 찍은 사진

요즘 필카의 매력에 푹 빠져있는중 ...ㅋㅋ

받아가실때는 댓글 센스를 보여주세요~♡

'사진 & 여행' 카테고리의 다른 글

청년 연택 계룡산 정복기!!  (0) 2009.11.30
어린이날 부천 로봇 댄스대회  (1) 2009.06.05
순천 & 여수 여행기  (1) 2008.10.10
선유도 공원 주변의 야경들...  (2) 2008.05.14
부산 여행 사진들  (1) 2008.05.14

+ Recent posts