레벨 트리거 방식은 입력 버퍼에 데이터가 남아있는 동안 계속해서 이벤트를 발생 시킨다.
위 그림을 보면, 1인 구간에서는 항상 이벤트가 발생된다.
반면 엣지 트리거 방식은 입력 버퍼에 데이터가 들어오는 순간(상태가 변하는 순간) 딱 한번만 이벤트를 발생 시킨다.
소켓은 기본적으로 레벨 트리거로 동작한다. 그 이후에 1로 유지되는 동안에는 발생하지 않는다.
여기서 소켓 통신을 예로 들어보자. 소켓 버퍼에 읽을 데이터가 있는 경우를 1, 없는 경우를 0으로 생각할 수 있다.
소켓 버퍼에 100바이트의 데이터가 도착했을 때, 소켓의 상태는 0에서 1로 변경된다. 이 때는 레벨 트리거나 엣지 트리거나 모두 이벤트를 발생 시킨다.
이제 사용자가 소켓 버퍼에서 데이터를 읽는다고 했을 때, 100바이트를 다 읽지 못하고 메모리 제한 등으로 30바이트만 읽었다고 하자. 그렇다면 여전히 소켓 버퍼에는 70바이트의 데이터가 남아 있다.
이 다음 상황에서, 레벨 트리거링을 하면, 소켓 버퍼에 데이터가 남아있기 때문에 여전히 이벤트가 발생하지만, 엣지 트리거링을 하면 소켓 버퍼의 상태(데이터가 존재하는 상태)가 변하지 않았기 때문에 이벤트가 발생하지 않는다.
그래서 엣지 트리거 기반으로 서버를 구현할 때는 두 가지가 필요하다.
<error.h>
를 포함하고, read()
나 write()
가 EAGAIN(EWOULDBLOCK
) 에러를 발생할 때, 즉 errno
변수에 EAGAIN
이 저장되어 있을 때만 트리거링을 한다.