얼랭과 예외처리 by thinkr

프로그래밍 언어마다 예외 처리의 구조는 대개 비슷하다. 그리고 얼랭도 예외(?)는 아니다. 조금 특이하다고 하면, 얼랭이 병행성을 다루는 관계로 다른 프로세스에서 발생한 예외를 처리하는 부분이 별도로 존재한다는 정도가 될 것이다. 따라서 얼랭에서의 예외 처리는 우선 기본적인 예외 처리 메커니즘을 살펴 보고, 이어서 병행 프로세스들 간의 예외 처리로 생각의 폭을 넓혀나가는 것이 좋다.

1. 기본적인 예외처리 메커니즘(단일 프로세스)

모든 얼랭의 문법이 그렇듯이, 예외 처리 역시 간단하다. 다음 한 문장이면 된다.

" 예외가 발생할 함수를 catch로 둘러쌀 것! "

예를 들어, foo/1이라는 함수가 발생할 수 있는 예외를 처리하려 한다면, catch 프리미티브를 사용하여 catch foo/1 과 같이 작성하면 된다. 이렇게 하면, foo/1이 정상적으로 처리되는 경우라면 통상적인 foo/1의 반환값이 반환되겠지만, 만약 뭔가 어떤 예외가 발생한 경우라면 {'EXIT', Reason}이 반환된다. 따라서 프로그램에서는 이 반환값을 매칭하여 적절한 처리를 해 주면 그만이다.
case (catch foo(...)) of
{'EXIT', Why} -> ...
Val -> ...
end
물론 최근에 새로 추가된 try...catch 문을 사용해도 된다. 그럴 경우라면 위 코드는 다음과 같이 될 것이다.
try foo(...) of
Val -> ...
catch
exit: Why -> ...
end

2. 하나 이상의 프로세스와 예외처리(병행 프로그래밍)

catch는 특정 프로세스 내에서 발생한 오류만을 "캐치"할 수 있으며, 다른 프로세스(예를 들면, spawned 프로세스)에서 발생한 오류는 "캐치"할 수 없다. 왜냐면 catch는 어떤 식의 계산(evaluation)을 모니터링하는 것이기 때문이다. 대신 다른 프로세스에서 발생한 오류는 그 프로세스가 발생시킨 종료 신호(signal)트랩(trap)함으로써 처리할 수 있다. 그런데, 그러려면 먼저 두 프로세스가 서로 연결(link)되어 있어야 한다.

두 프로세스 P1과 P2가 서로 연결된 상태에서 상대편 프로세스(P1)에서 오류가 발생하면, 연결된 프로세스(P2)로 종료신호가 전달되는데, 그 시그널의 종류는 크게 정상(normal)과 비정상(normal이 아님)의 두 가지이다.
이제 이 종료신호를 받은 P2는 어떻게 할까? 여러 가지 경우의 수가 있겠지만, 기본적으로는 다음과 같이 작동한다.

그 신호가 정상(normal) 신호인 경우
무시하고 그냥 하던 일을 계속한다.
그 신호가 비정상 신호인 경우(즉, normal이 아닌 경우)
자신은 죽고, 다시 그 신호를 자신과 연결된 다른 프로세스들로 전파한다.

이게 기본적인 동작인데, 물론 비정상 신호가 와도 죽지 않게 할 수도 있다. 이 때 사용하는 함수가 바로 process_flag/2이며, 이렇게 process_flag(trap_exit, true)를 사용하여 "불사신"이 된 프로세스를 가리켜 흔히 시스템 프로세스라고 부른다. 시스템 프로세스로 비정상 신호가 들어올 때는, 종료 신호가 통상적인 메시지 형태, 즉 {'EXIT', FromPid, Reason}의 형태로 변환되기 때문에, 프로그램에서는 일반적인 메시지 처리 루틴에 따라 처리하면 되는 것이다.

백견이 불여일타!

덧글

  • ikspres 2008/08/07 07:57 # 삭제

    예외처리를 한 큐에 배울 수 있었습니다. 감사^^
※ 이 포스트는 더 이상 덧글을 남길 수 없습니다.



Follow me on Twitter

Follow sjoonk on Twitter