앞 선 글 중 ‘std::thread - 2. Join’에서 join을 호출하지 않은 경우 에러 창이 발생하였습니다.


 

이것은 C++11 thread 사양에 의해서 thread 오브젝트가 파괴될 때 join이나 detach를 호출하지 않은 경우 std::terminate를 호출하여 프로그램을 종료하도록 되어 있기 때문입니다.

 

< 예제. 9 >

#include <thread>

#include <iostream>

 

int main()

{

           int nThreadRunCount = 0;

          

           {

                      std::thread Thread = std::thread( [&] ()

                       {

                          for( int i = 0; i < 10; ++i )

                          {

                                ++nThreadRunCount;

                                                               

                                std::cout << "Thread1 ID : " << Thread.get_id() << std::endl;

                          }

                       } );

           }

 

           getchar();

           return 0;

}

 


<예제.9>를 실행하면 에러가 발생하고 아래의 콜스택을 보면



thread 오브젝트의 소멸자에서 terminate를 호출하는 것을 알 수 있습니다.



이것으로 thread에 대해서 기능 위주로 간단하게 살펴 보았습니다. 앞으로 공부해야 할 것들이 더 있어서 남은 것들을 설명 후 다시 thread 사용에 대해서 깊게 들어 가겠습니다.

 

다음부터는 병렬 프로그래밍에서 절대 빠질 수 없는 동기화 객체에 대해서 설명하겠습니다.

 

 

저작자 표시
신고
by 흥배 2013.05.28 08:00





저작자 표시
신고
by 흥배 2013.04.23 21:22

예전에 적은 글을 출판사에서 편집을 해서 이번에 무료 이북으로 나왔습니다.

STL 초보자 용 책이라고 보시면 됩니다. 
필요하신 분들은 다운로드 하세요^^

http://www.hanb.co.kr/ebook/look.html?isbn=9788979149937#binfo2



저작자 표시
신고
by 흥배 2012.12.22 14:21

int, short, float 타입 등의 수치 타입의 최대 값과 최소 값을 알고 싶을 때는 

STL에 있는 nurmeric_limit를 사용합니다.


너무 간단한 내용이니 아래의 예제 코드로 설명을 끝내겠습니다^^


#include <iostream>

#include <limits>


int main()

{

std::cout << "float 타입의 최대 값:  " << std::numeric_limits<float>::max( ) << std::endl;

std::cout << "double 타입의 최대 값:  " << std::numeric_limits<double>::max( ) << std::endl;

std::cout << "short 타입의 최대 값:  " << std::numeric_limits<short>::max( ) << std::endl;

std::cout << "int 타입의 최대 값:  " << std::numeric_limits<int>::max( ) << std::endl;

std::cout << "short 타입의 최대 값:  " << std::numeric_limits<short>::max( ) << std::endl;

std::cout << "__int64 타입의 최대 값:  " << std::numeric_limits<__int64>::max( ) << std::endl;



std::cout << "float 타입의 최소 값:  " << std::numeric_limits<float>::min( ) << std::endl;

std::cout << "double 타입의 최소 값:  " << std::numeric_limits<double>::min( ) << std::endl;

std::cout << "short 타입의 최소 값:  " << std::numeric_limits<short>::min( ) << std::endl;

std::cout << "int 타입의 최소 값:  " << std::numeric_limits<int>::min( ) << std::endl;

std::cout << "short 타입의 최소 값:  " << std::numeric_limits<short>::min( ) << std::endl;

std::cout << "__int64 타입의 최소 값:  " << std::numeric_limits<__int64>::min( ) << std::endl;


return 0;

}


< 결과 >







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

이번에 설명할 is_partitioned, partition_point는 그 이름처럼 앞서 소개한 partition_copy와 관계가 있는 알고리즘 입니다.

 

is_partitioned의 원형

template<class InputIterator, class BinaryPredicate>

    bool is_partitioned(

        InputIterator _First,

        InputIterator _Last,

        BinaryPredicate _Comp

    );

 

partition_point의 원형

template<class ForwardIterator, class Predicate>

    ForwardIterator partition_point(

        ForwardIterator _First,

        ForwardIterator _Last,

        Predicate _Comp

    );

 

is_partitioned는 데이터셋의 요소가 전반 부와 후반 부 두 개로 나누어져 있는지 조사할 때 사용하고, partition_point는 두 개로 나누어져 있는 데이터셋에서 후반 부의 첫 번째 요소를 가리키는 반복자를 반환합니다.

 

약간 설명이 애매하죠?^^; 

예를 들어 설명하면 온라인 FPS 게임에서 8명이 각각 4명씩 레드 팀과 블루 팀으로 나누어서 게임을 하는 경우 vector로 된 StagePlayers(온라인 게임에서 방에 들어온 유저들을 저장)에 앞 부분에는 레드 팀 플레이어 4명을 차례로 저장하고그 이후에 블루 팀 플레이어를 저장하고 있는지 조사하고 싶을 때 is_partitioned알고리즘을 사용하면 알 수 있습니다(맞다면 true를 반환합니다). 그리고 StagePlayers에서 블루 팀의 첫 번째 플레이어에 접근하고 싶다면 partition_point를 사용합니다.  


나름 쉽게 설명한다고 했는데 이해 가시나요만약 이해가 안 간다면 예제 코드를 봐 주세요^^

 

예제 >

#include <iostream>

#include <algorithm>

#include <vector>

#include <list>

using namespace std;

 

struct PLAYER

{

           int CharCD;

           bool IsRedTeam;

};

 

 

int main()

{

           vector< PLAYER > StagePlayers1;

           PLAYER player1; player1.CharCD = 1;         player1.IsRedTeam = true;          StagePlayers1.push_back( player1 );

           PLAYER player2; player2.CharCD = 2;         player2.IsRedTeam = true;          StagePlayers1.push_back( player2 );

           PLAYER player3; player3.CharCD = 3;         player3.IsRedTeam = true;          StagePlayers1.push_back( player3 );

           PLAYER player4; player4.CharCD = 4;         player4.IsRedTeam = false;                     StagePlayers1.push_back( player4 );

           PLAYER player5; player5.CharCD = 5;         player5.IsRedTeam = false;                     StagePlayers1.push_back( player5 );

           PLAYER player6; player6.CharCD = 6;         player6.IsRedTeam = false;                     StagePlayers1.push_back( player6 );

           PLAYER player7; player7.CharCD = 7;         player7.IsRedTeam = false;                     StagePlayers1.push_back( player7 );

 

           bool IsPartitioned = is_partitioned( StagePlayers1.begin(), StagePlayers1.end(),

                                                                                     []( PLAYER player ) -> bool { return player.IsRedTeam; } );

           if( IsPartitioned ) {

                     cout << "레드 팀과 블루 팀으로 구분 되어 나누어져 있습니다." << endl;

           } else {

                     cout << "레드 팀과 블루 팀으로 구분 되어 있지 않습니다." << endl;

           }

 

           vector< PLAYER >::iterator IterFirstBlueTeamPlayer = partition_point( StagePlayers1.begin(),StagePlayers1.end(),

                                                     []( PLAYER player ) -> bool { return player.IsRedTeam; } );

           if( IterFirstBlueTeamPlayer != StagePlayers1.end() ) {

                     cout << "첫 번째 블루 팀 플레이어캐릭터 코드 : " << (*IterFirstBlueTeamPlayer).CharCD << endl;

           }

 

                    

           vector< PLAYER > StagePlayers2;

           StagePlayers2.push_back( player7 );

           StagePlayers2.push_back( player6 );

           StagePlayers2.push_back( player1 );

           StagePlayers2.push_back( player5 );

           StagePlayers2.push_back( player4 );

           StagePlayers2.push_back( player3 );

           StagePlayers2.push_back( player2 );

          

           IsPartitioned = is_partitioned( StagePlayers2.begin(), StagePlayers2.end(),

                                                                                     []( PLAYER player ) -> bool { return player.IsRedTeam; } );

           if( IsPartitioned ) {

                     cout << "레드 팀과 블루 팀으로 구분 되어 나누어져 있습니다." << endl;

           } else {

                     cout << "레드 팀과 블루 팀으로 구분 되어 있지 않습니다." << endl;

           }

 

           getchar();

           return 0;

}

 

결과 >

 

예제 코드를 보니 쉽게 이해 되시죠그럼 저는 아는 걸로 생각하고 다음 포스팀에서는 다른 알고리즘을 설명하겠습니다^^

저작자 표시
신고
by 흥배 2012.09.05 19:26

VC11 STL 컨테이너들은 이전 버전에 비해서 크기가 작아져서 메모리를 절약할 수 있게 되었습니다. 이전 버전과 다르게 VC11부터는 데스크탑 뿐만이 아닌 테블렛이나 스마트폰의 모바일 플랫폼 개발에서도 사용되므로 메모리 절약은 적지 않은 도움이 되리라 생각합니다.

 

아래 표는 x86(32비트 또는 ARM) x64(64비트) 플랫폼에서 각 VC 버전 별로 얼마만큼의 메모리를 사용하는 잘 표시하고 있습니다.

 

이 표는 VC11 뿐만이 아닌 이전 버전 사용자들에게도 도움이 될 것 같습니다. 저와 같은 서버 프로그래머들은 서버 프로그램이 설정한 동접자 수에서 어느 정도의 메모리를 소비할지 어느 정도 계산하고 있어야 하는데 이 표를 보면 메모리 계산할 때 도움이 될 것입니다

 

표의 바이트 사이즈는 Release 버전 기준입니다. 표에서 'VC9 SP1 SCL=0'SCL _SECURE_SCL를 뜻하는 것으로 원래 SCL은 기본은 1인데, 최고 스피드를 위해서 수동으로 SCL0으로 설정한 것입니다. VC10 VC11에서는 기본으로 _SECURE_SCL 0으로 되어 있습니다.

 


표의 출처는 MSDN입니다^^




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

예전에  http://jacking.tistory.com/154 이 글을 통해서 간단하게 VC++의 연관 컨테이너의 성능을 테스트해 본적이 있습니다.

그 때는 VC++ 9 환경에서 테스트를 했는데 이번에는 VC++ 11(RC)에서 테스트 해 보았습니다.

그때 사용했던 코드를 거의 그대로 사용했습니다(그래서 손 볼 것이 좀 있습니다^^;)


성능은 역시나(?) CAtlmap이 제일 빠릅니다. 또 unordered_map이 이전에 비해서 많이 빨라졌네요

일전에 VC++ 팀 블로그에서 성능이 개선되었다고 하던데 맞네요


코드를 올리니 혹시 관심 있는 분들은 좀 더 다양하게 테스트 해보시고 공유 부탁합니다^^





ContainerPerformance.zip


저작자 표시
신고
by 흥배 2012.07.05 09:00
C++, STL

일본의 콘솔 게임 개발자의 글을 웹서핑 중 보고 옮겨봅니다.

 

운 좋게 STL에 대해서 거부감 없는 곳에서 일하고 있지만 어떤 곳에서는 STL은 게임 개발에는 적합하지 않다고 사용을 금지하는 곳이 있음(역주 :제 기억으로 한국도 2002~5년 정도까지는 커뮤니티에서 STL로 불꽃(?) 토론이 있었죠. 아마 GPGStudy에 가면 아직 글이 있을 듯하네요).

 

STL은 그 특성을 잘 모르면 골치 아플 수 있음. 특히 콘솔 게임기는 메인 메모리가 PC에 비해서 엄청나게 작은데 그 작은 메모리로 실행 바이너리나 힙 영역으로 사용해야 한다. 메모리 관리에 대해서 엄격하므로 template는 사용 방법에 따라서 바이너리 사이즈가 켜져서 사용을 어느 정도 제한할 수 밖에 없음(역주 : 저 개인적으로 이 메모리 관리 때문에 PC 개발만 해 본 사람은 콘솔 게임 개발이 무척 어려울 것이라고 생각합니다).

 

std::list, std::map 등은 사용하면 사용할수록 내부에서 메모리 단현화 시키므로 힙 영역의 총 량은 남아있지만 사용 가능한 용량이 부족하게 되는 경우가 있다. 그래서 본인이 있는 곳에서는 모든 게임 코드에 std::list, std::map 등의 메모리 단편화를 만드는 컨테이너는 사용을 피하도록 하고 있으며 만약 신입이 깜박하고 사용한 경우에는 왜 게임에서 사용하면 안 되는지 알려주고 구조를 바꾸도록 한다.

 

그런데 어떤 게임 개발 회사의 개발자가 만든 책에는 std::vector를 혹평하고 std::map을 절찬한 경우가 있다.

 

STL을 금지 시키는 사람의 가장 큰 이유는 자신이 STL이 무엇인지 잘 모른다는 것. 보통 STL 이라고 하면 컨테이너만 생각하는데 컨테이너 + 이터레이터 + 알고리즘 + functor 이다. 알고리즘은 STL 컨터이너 뿐만이 아닌 배열도 사용할 수 있다.

 

출처 : http://d.hatena.ne.jp/masfj/20120308/1331220846

 

 

 

ps : 제 경험으로도 애자일, TDD, STL, boost 라이브러리 등을 반대하는 사람들은 대부분 아는 사람이 아니고 잘 모르는 사람이 반대하더군요(왠지 적어보니 당연한 것 같기도 ㅎㅎ). 그래서 반대 논리가 너무 빈약하고 억지에 가까운 자신의 생각만을 이야기 하더군요(당연하지만 본인은 절대 객관적이라고 이야기하죠).

저작자 표시
신고
by 흥배 2012.04.12 09:00
C++, STL
한빛미디어의 한빛네트워크 사이트에 연재하던 STL 연재가 끝났습니다.




앞으로는 이 글을 토대로 완전한 글을 적는 것이 남았습니다.
현재 계획은 TR1, C++0x, Boost, ATL의 컨테이너까지 넣을 생각입니다.
저작자 표시
신고
by 흥배 2009.11.23 09:00
C++, Set, STL
앞서 설명했던 map과 비슷하면서도 다른 set을 이번에 이야기 하려고 합니다. map 이전에는 hash_map을 설명했는데 이번에 이야기할 set과 여러 부분에서 중복되는 부분이 있고, 저는 현업에서 set을 사용하는 경우가 거의 없어서 이번에는 내용이 길지 않을 것 같습니다.

8.1 set 이란

set은 원하는 key를 신속하게 찾고, 또 이 key가 정렬되기를 원할 때 사용합니다.(여기서 말하는 key라는 것은 저장할 자료를 말합니다). map과 비슷하지만 다른 점은 map은 key와 값이 한 쌍으로 저장하지만 set은 key만 저장합니다. set도 map과 같이 key를 중복으로 저장할 수 없습니다. 만약 key를 중복으로 사용하고 싶다면 multiset을 사용해야 합니다. 사용방법은 set과 거의 같습니다. set은 map과 같이 이진 탐색 트리 자료구조를 사용합니다.

8.2 set을 사용할 때

앞서 이야기 했듯이 set은 자료를 저장할 때 내부에서 자동으로 정렬하고, map과 다르게 key만 저장합니다.

set은 아래 조건일 때 사용하면 좋습니다.
  1. 정렬해야 한다.
  2. key가 있는지 없는지 알아야 할 때
  3. 많은 자료를 저장하고, 검색 속도가 빨라야 할 때
다른 컨테이너를 설명 할 때 꽤 많은 이야기를 했는데 그동안 했던 이야기와 중복되는 것이 많고 특히 앞의 map과 비슷한 부분이 많아서 이번에는 바로 사용 방법으로 들어가겠습니다.
.........................
..............................
나머지는 여기서 보세요^^;




저작자 표시
신고
by 흥배 2009.08.27 18:10
| 1 2 |

티스토리 툴바