2009년 10월 17일

소켓에서 발생하는 이벤트 감지의 기준. edge trigger와 level trigger

두 트리커의 차이점은 소켓버퍼에 데이터가 있는 경우에 그것을 소켓 이벤트로 간주하는 기준이다.

먼저, 쉬운것부터...

레벨트리거: 소켓버퍼에 데이터가 들어있으면 무조건 이벤트가 발생하는 트리거이다. 즉, 소켓에서 read 할 수 있는 데이터가 1바이트 이상 있을때 이벤트가 발생했다고 리턴해준다. 여기서 1바이트라고 했지만 그 기준을 소켓옵션설정을 통해 조정할 수 있는 것으로 알고 있다. 이것을 조정하면 10바이트 이상일 경우에만 이벤트가 발생하는 것으로 기준을 설정할 수도 있다. (select(), poll() 등이 레벨트리거에 속한다.)

에지트리거: 소켓버퍼의 데이터가 들어오는 시점을 알려주는 이벤트 트리거이다. 소켓버퍼가 비어 있다가 상대방으로부터 버퍼에 데이터가 들어오면 이때 이벤트가 발생한 것으로 간주한다. 들어온 데이터를 어플리케이션에서 read 하고 안하고는 무관하다. 즉, 에지트리거에서 이벤트가 발생했고(데이터가 들어왔고), 어플리케인션에서 read 하지 않더라도 그 이후에 다른 데이터가 추가로 들어오면 에지트리거는 이벤트가 발생했다고 리턴하게 된다. (epoll(), kqueue() 등이 에지트리거에 속한다. 이것들은 설정에 따라 레벨트리거로도 사용할 수 있다.)

일반적으로.... 에지트리거가 대량의 접속시에 더 나은 응답속도를 제공한다.
(이벤트 처리가 빠르다.)

이해를 돕기 위해서 그림하나 추가해 본다.





에지트리거를 다룰 때 주의점:
에지트리거를 통해 이벤트 받았고 read 작업을 해야하는데, 이 시점에 read 할 수 있는 모든 데이터를 read 해야한다. 왜냐하면, 에지트리거는 데이터 유입에 대한 이벤트이므로 추가로 데이터 유입이 없으면 이벤트가 오지 않으므로 이번 이벤트를 통해 read를 할 때 다음에 다시 이벤트가 온다는 보장이 없으므로 이 시점에 읽을 수 있는 모든 데이터를 read 해야만 정상적인 처리가 된다. 어플리케이션의 read 버퍼가 작아서 꽉찬 상태로 리턴되면 이것을 다른 버퍼에 저장해 두고, 나머지를 다시 소켓으로부터 read 해야한다. 더 읽을 것이 없을때까지 계속 read 해야 한다. 이번에 read를 다 하지 않으면 영원히 다시 read할 이벤트가 오지 않을 수 있기 때문이다.

댓글 없음:

댓글 쓰기