19
Exceptions CGCII Cho sanghyun’s Game Classes II

GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

  • Upload
    -

  • View
    141

  • Download
    0

Embed Size (px)

Citation preview

Page 1: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

ExceptionsCGCIICho sanghyun’s Game Classes II

Page 2: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

Basic concept of Pool System

예외 (Exception) 처리

CGCIICho sanghyun’s Game Classes II

예외처리

근데 도대체 왜 이런 악를 만들었을까 ?? ‘ 스트로스트럽’은 진정 악를 만들었나 ?

= 잉여 ! 존재 악 !try, throw, catch!

왜냐 ! 첫째 , 속도가 느려진다 .

왜냐 ! 둘째 , 디버깅 힘들다 .

왜냐 ! 셋째 , 귀찮다 .

왜냐 ! 네째 , 다중상속과 함께 C++ 의 2 대 악 ! 일까 ?

[ 창시자 ]예외 킹왕짱 !!

꼭 쓰셈

[ 창시자 ]예외 킹왕짱 !!

꼭 쓰셈

비야네 스트로스트롭

[ 사상가 ]예외 ? 잘 알고 쓰셈

잘 알면 넘 비쌈

[ 사상가 ]예외 ? 잘 알고 쓰셈

잘 알면 넘 비쌈

스캇 마이어

[ 사고처리 전문가 ]예외 ?!

예외 쓰면 해고시키셈

[ 사고처리 전문가 ]예외 ?!

예외 쓰면 해고시키셈

존 로빈C++ 창시자 EC++, MEC++ Debugging Application .NET…

Page 3: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

예외란 ?예외처리

File OpenFile Open

Read ARead A

Read BRead B

Read CRead C

File Type?File

Type?

구현하고자하는 주 흐름 !!

File CloseFile Close

File 없다 !File 없다 !

File 열 수 없다!

File 열 수 없다!

읽을수 없다 !읽을수 없다 !

모르는 Type!!모르는 Type!!

못 읽는다 !못 읽는다 !

예외 !!

읽기 싫다 !읽기 싫다 !

예외란 ??

예외와 주흐름은 반드시 구분되어야 한다 . 예외는 프로그래밍에 있어서는 재해 상황이나 마찬가지다 .

재난 !!!

Page 4: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

C++ 예외예외처리

try{

if(error)throw (int)1;

…if(error)

throw “Test Error”;}

catch(int p_a){

printf(“Error1 Catch\n”);

throw;}

catch(const char* p_String){

printf(“Error2 Catch\n”);}

printf(“ 그다음에 여기 실행 !”);

try{

if(error)throw (int)1;

…if(error)

throw “Test Error”;}

catch(int p_a){

printf(“Error1 Catch\n”);

throw;}

catch(const char* p_String){

printf(“Error2 Catch\n”);}

printf(“ 그다음에 여기 실행 !”);

Reraise ( 화재 발생 전파 !!)• Catch 한 것으로 그대로 다시 throw 하는 것 !• Catch 블록 안에서만 쓸 수 있는 것 .

Throw ( 화재 발생 경보 발생 ! )• Exception 을 던진다 .

catch ( 대기중인 비상 시 처리반 !!)• 받은 Catch 에서 예외 상황을 처리한다 .

Page 5: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

C++ 예외 스택 되감기예외처리

void TestXXX(){ int X;

if(…) throw 5;}void TestFunction (){ std::vector<int> Y; try { TestXXX(); }

catch(char* e) { printf(“ 잡았슈 \n”); }

catch(int a) { printf(“ 잡았슈 \n”); }

void TestXXX(){ int X;

if(…) throw 5;}void TestFunction (){ std::vector<int> Y; try { TestXXX(); }

catch(char* e) { printf(“ 잡았슈 \n”); }

catch(int a) { printf(“ 잡았슈 \n”); }

catch(int e)

catch(char* e)

StackException!!Exception!!

CallReturn AddressReturn Address

YY

Catch(char*)Catch(int)

Catch(char*)Catch(int)

Return AddressReturn Address

XXCall

스택 되감기 (Stack Unwinding) 은 예외처리 원리의 핵심이닷 !!! 스택 되감기 (Stack Unwinding) 은 평소에는 다니지 않는 비상 계단 !!!

Stack Unwinding

Page 6: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

예외란 ?예외처리

예외를 발생시켜 처리하면 부하가 많이 걸린다 ???

• 하지만 !! 신경 쓸 필요 없다 !!! 예외가 발생했다면 그건 이미 망했음을 의미하니까 !

YES!

• 예외 발생시 부하를 걱정하는 것은 예외를 정상 처리 과정과 혼돈하는 증상 !!

• 예외의 발생이란 쉽게 말해서 집에 불이 난 것을 의미함 !!

• 따라서 예외를 던지는 건 것은 화재 비상벨을 울리는 행위로 그만큼 신중해야 한다는 것 !

• 예외 처리를 한다는 것이 재난 대비 메뉴얼을 준비해 놓는 것 !

Page 7: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

예외란 ?예외처리

try-catch 블럭을 쓰는 것만으로 성능 떨어진다 ??

• 이건 어쩔 수 없다 .!!! – 화재 대비용으로 배치된 소화기가 걸리적 거린다는 것과 같음 .• 하지만 차이는 사실상 없다고 할 수 있다 !

어차피 예외를 쓰지 않아도 예외처리 하려면 if 문 같은 것을 써야 하니까 . 차이는 미미해진다 .

YES!

Page 8: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

예외란 ?예외처리

• 예외처리는 비상 사태를 처리하기 위한 공고한 프로그래밍의 수단일 뿐이지…보다 우아한 프로그래밍을 위한 것이 아니다 .

어 ~ 그럼 어차피 망한 거라면 뭣 하러 힘들게 예외 처리를 할 필요가 있나 ??

• 공고함 (Robust) 을 요구하는 곳에서는 필요하다 .

있을 수도 있다 !!

Page 9: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

예외 처리 기본 개념

예외 처리의 기본 개념은… 재난 처리 시스템

예외 안전 (Exception Safe)

예외 중립 (Exception Neutral)

예외 안전은 예외 발생시 적절한 처리를 하는 것을 말함 .

예외 발생을 적절한 처리자 ( 호출자 ) 에게까지 전달하는 것 (Reraise 가 핵심 )재난이 발생하면 재난 처리 지휘부에 까지 재난 발생이 전달되어야 한다 .

예외 안전은 보장은 3(+1) 가지 레벨로 나뉨 .

* No Exception Guarantee 1.Basic Exception Guarantee2.Strong Exception Guarantee3.No-Throw Exception Guarantee

예외처리

적절한 재난 처리를 위해 아래의 두 가지 개념이 필요하다 .

Page 10: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

예외 안전 보장이란 ?

예외 안전 ( 화재 안전 ) 보장의 수위란…

만약 화재 ( 예외 ) 가 발생한다면 …

1. 화재 대비가 뭔가요 ? 먹는 건가요 ??? 까지꺼 다 타면 새로 짓죠 . 대비란 없다 .

No Exception Guarantee

예외처리

• 아무런 보장하지 않는 수준 – 예외 발생하면 모든 사태를 그냥 받아 들이겠다 .

• 상용 소프트웨어에서 이 상태는 있을 수 없음 .

Page 11: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

예외 안전 보장이란 ?

2. 그냥 인명피해 없이 안전하게 탈출 할수 있는 수준으로만 대비하겠다 !!!

Basic Exception Guarantee

예외처리

• 예외 발생시 메모리 릭 등 아무런 스트레스를 남기지 않는 것을 보장 .• 기본 예외 보장은 예외 발생 후 안전한 종료 정도만 보장하는 레벨 .

Page 12: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

예외 안전 보장이란 ?

3. 인명 피해 방지는 기본 ! 바로 불난 곳만 처리하고 계속 일할 수 있도록 대비하겠다 !!!

Strong Exception Guarantee

예외처리

• 기본 보장에 추가로 수행 혹은 되돌림 (Commit or Rollback) 을 보장해주는 것 .• 강한 보장은 예외 발생 전 상황으로 완전히 되돌림 (Rollback) 을 보장해 주는 것 .• 강한 보장은 예외 발생 후에도 동작 수행 가능을 보장하는 레벨 .• 일반적인 API, 일반적인 STL 등이 지원하는 레벨 .

Page 13: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

예외 안전 보장 (Exception Safe Guarantee)

• 예외를 절대 던지지 않는 다는 것을 보장해주는 레벨 .• 일반적으로 소멸자 , 제거 , 종료 등 예외 처리 중 실행될 수 있는 함수는 반드시 제공해

야 하는 수준 .• 예외 처리 중 실행되는 함수들이 이 레벨을 지원하지 않으면 무한 예외 발생 가능함 .

예외처리

4. 화재 자체가 절대 날수 없도록 하겠다 ! ( 대피 통로는 그래야 하지 않을까 ?)

No-Throw Exception Guarantee

Page 14: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

예외 안전 보장 (Exception Safe Guarantee)

void foo::function(int* p_arrayValue, int p_Amount){

char*temp = new char[256];…

for(int i=0; i< p_Amount; ++i){

m_list->push_back(p_arrayValue[i]);if(…){

throw std::exception();}

}

delete temp;}

void foo::function(int* p_arrayValue, int p_Amount){

char*temp = new char[256];…

for(int i=0; i< p_Amount; ++i){

m_list->push_back(p_arrayValue[i]);if(…){

throw std::exception();}

}

delete temp;}

아래 코드는 예외 안전한가 ?

예외발생시 temp 를 delete 하지 않고 빠져나감 !예외 처리시 메모리릭 발생 !

예외발생

결론적으로 예외 안전하지 않음 !

예외처리

Page 15: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

기본 예외 안전 보장 (Basic Exception Garantee)(1)

void foo:: function(int* p_arrayValue, int p_Amount){ char* temp = NULL; // 메모리들을 초기화 .

try { temp = new char[256]; // 메모리들을 할당한다 . for(int i=0; i< p_Amount; ++i) { m_list->push_back(p_arrayValue[i]); if(…) { throw std::exception(); } }

delete temp; } catch(...) { SAFE_DELETE(temp); throw; }}

void foo:: function(int* p_arrayValue, int p_Amount){ char* temp = NULL; // 메모리들을 초기화 .

try { temp = new char[256]; // 메모리들을 할당한다 . for(int i=0; i< p_Amount; ++i) { m_list->push_back(p_arrayValue[i]); if(…) { throw std::exception(); } }

delete temp; } catch(...) { SAFE_DELETE(temp); throw; }}

아래 코드는 예외 안전에 대해 기본 보장 (Basic Guarantee) 를 제공한다 !

Re-Raise (Exception Neutral 달성 )안전하게 제거 ! (Basic Guarantee 달성 )

예외발생

Reraise

예외처리

Page 16: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

기본 예외 안전 보장 (Basic Exception Garantee)(2)

void foo:: function(int* p_arrayValue, int p_Amount){ auto_ptr<char> temp(new char[256]);

for(int i=0; i< p_Amount; ++i) { m_list->push_back(p_arrayValue[i]); if(…) { throw std::exception(); } }}

void foo:: function(int* p_arrayValue, int p_Amount){ auto_ptr<char> temp(new char[256]);

for(int i=0; i< p_Amount; ++i) { m_list->push_back(p_arrayValue[i]); if(…) { throw std::exception(); } }}

스마트 포인터 같은 것을 사용하면 훨씬 간단하게 Basic Guarantee 를 구현 가능하다 .

예외 발생시 Stack Unwinding 과정에서 소멸자가 호출되며 delete 됨 (Basic Guarantee 달성 !)

그렇다면 위 Code 는 Strong Guarantee 를 제공하는가 ?

NoRollback 처리가 되지 않았다 ! → m_list 값이 원상복구 되지 않는다 !

예외처리

Page 17: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

강한 예외 안전 보장 (Strong Exception Guarantee)

void foo:: function(int* p_arrayValue, int p_Amount){ char* temp = NULL; // 메모리들을 초기화 . int i = 0;

try { temp = new char[256]; // 메모리들을 마구 할당한다 . for(i=0; i< p_Amount; ++i) { m_list->push_back(p_arrayValue[i]); if(…) { throw std::exception (); } } delete temp; } catch(...) { SAFE_DELETE(temp); for(int j=0;j<i; ++j) m_list->pop_back(); throw; }}

void foo:: function(int* p_arrayValue, int p_Amount){ char* temp = NULL; // 메모리들을 초기화 . int i = 0;

try { temp = new char[256]; // 메모리들을 마구 할당한다 . for(i=0; i< p_Amount; ++i) { m_list->push_back(p_arrayValue[i]); if(…) { throw std::exception (); } } delete temp; } catch(...) { SAFE_DELETE(temp); for(int j=0;j<i; ++j) m_list->pop_back(); throw; }}

예외 발생시 완전 Rollback 처리 !(Strong Guarantee 달성 !)

아래 코드는 예외 안전에 대해 강한 보장 ( Strong Guarantee) 를 제공한다 !

Rollback 처리를 위해

예외처리

Page 18: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

무 - 예외 안전 보장 (No throw Exception Guarantee)

No Throw Guarantee 는 앗사리 예외를 밖으로 내보내지 않는 것 ! 대부분 성공 때까지 재시도를 하는 것이 아니라 예외를 내부에서 다 삭히도록 처리한다 .

foo::~foo(){

try{

function();}catch(…){}

}

foo::~foo(){

try{

function();}catch(…){}

}

예외 중립을 처리하지 않는다 ! 이로써 예외를 그냥 우걱우걱 !이것으로 No Throw Guarantee!!

예외처리

void function(){

…if(..)

throw std::exception();…

}

foo::~foo(){

function();}

void function(){

…if(..)

throw std::exception();…

}

foo::~foo(){

function();}

함수의 호출 중 예외가 발생할 수 있다 !!!

Page 19: GCGC- CGCII 서버 엔진에 적용된 기술 (3) - Exception

CGCIICho sanghyun’s Game Classes II

질문 ?예외처리

질문 [email protected]