'리소스'에 해당되는 글 2건

  1. 2011.10.03 리소스 할당과 해제의 균형과 예외
  2. 2011.10.03 리소스의 할당과 해제

리소스 할당과 해제의 균형과 예외

Posted by epicdev Archive : 2011. 10. 3. 13:45
예외를 지원하는 언어는 리소스 해제에 복잡한 문제가 있을 수 있다. 예외가 던져진 경우, 그 예외 이전에 할당 된 모든 것이 깨끗이 청소된다고 어떻게 보장 할 수 있겠는가?


C++에서 예외와 리소스 사용의 균형

C++은 try...catch 예외 메커니즘을 지원한다. 불행하게도, 이 말은 예외를 잡은 다음 다시 던지는 루틴에서는 언제나 그 루틴에서 나가는 경로가 최소한 두 개는 존재한다는 얘기다.

void doSomething(void) {
    Node* n = new Node;
    try {
        // Do something
    } catch(...) {
        delete n;
        throw;
    }
    delete n;
}

우리가 생성한 노드가 해제되는 장소가 두 군데라는 점을 눈여겨보라. 하나는 루틴이 정상적으로 나가는 경로에 있고, 다른 하나는 예외처리 장소에 있다. 이것은 명백한 Don't repeat yourself 원칙 위반이며, 언제 터질지 모르는 유지보수 문제이기도 하다.

하지만 우리는 C++의 작동방식을 이용 할 수 있다. local 객체들은 자기를 둘러싼 블록에서 나갈 때 자동으로 파괴된다. 이것 덕분에 몇 가지 방법이 생긴다. 만약 상황이 허락한다면, 'n'을 포인터에서 스택에 놓이는 실제 Node 객체로 바꾸면 된다.

void doSomething(void) {
    Node n;
    try {
        // Do something
    } catch(...) {
        throw;
    }
}

이렇게 되면 예외가 생기든 그렇지 않든 Node 객체의 자동 파괴를 C++에게 맡길 수 있다.

포인터에서 다른 것으로 바꾸는 일이 불가능 하다면, 리소스를 다른 클래스로 감싸면 동일한 효과를 볼 수 있다.

class NodeResource {
    Node* n;
public:
    NodeResource() { n = new Node; }
    ~NodeResource() { delete n; }
    Node* operator->() { return n; }
};

void doSomething(void) {
    NodeResource n;
    try {
        // Do something
    } catch(...) {
        throw;
    }
}

이제 wrapper 클래스 NodeResource가 자신의 객체들이 파괴 될 때 관련 노드들 역시 파괴되도록 하는 일을 확실히 해준다. 편의성을 위해, wrapper 클래스는 -> 연산자도 제공해서 사용자가 Node 객체에 들어있는 필드에 바로 접근 할 수 있게 해준다.
이 기법이 너무나도 유용하기 때문에, 표준 C++ 라이브러리에도 동적으로 할당 된 객체들의 자동 wrapper를 제공하는 템플릿 클래스 auto_ptr이 있다.
void doSomething(void) {
    auto_ptr p (new Node);
    try {
        // Do something
    } catch(...) {
        throw;
    }
}

자바에서 리소스 사용의 균형


public void doSomething() throws IOException {
    File tmpFile = new File(tmpFileName);
    FileWriter tmp = new FileWriter(tmpFile);
    try {
        // Do something
    } catch(...) {
        // Do something
    } finally {
        tmpFile.delete();
    }
}

이 루틴에서 사용하는 임시파일은 루틴에서 어떻게 나가든 지워야 한다. Finally 블록이 우리가 뜻하는 바를 이렇게 간결하게 표현 해 준다.


 
  

리소스의 할당과 해제

Posted by epicdev Archive : 2011. 10. 3. 13:22
리소스를 할당한 순서의 반대로 해제하라. 이렇게 해야 한 리소스가 다른 리소스를 참조하는 경우에도 리소스를 고아로 만들지 않는다.

코드의 여러 곳에서 동일한 리소스 집합을 할당하는 경우, 할당 순서를 언제나 같게 하라. deadlock 가능성이 줄어들 것이다. (프로세스 B가 리소스2를 이미 확보하고서 리소스1을 획득하려고 하고 있는데 프로세스 A가 리소스1을 가진 상태로 리소스2를 요청하려고 한다면, 이 두개의 프로세스는 영원히 기다리게 될 것이다.)

어떤 종류의 리소스를 사용하고 있는지는 중요하지 않다. 트랜잭션이나 메모리이건, 파일 혹은 쓰레드, 윈도우이건 모두 기본 패턴이 적용된다. 리소스를 할당하는 것이 누구이든, 그 리소스를 해제할 책임까지 져야 한다.

 
실용주의프로그래머
카테고리 컴퓨터/IT > 프로그래밍/언어
지은이 앤드류 헌트 (인사이트, 2007년)
상세보기
  
 «이전 1  다음»