기본 콘텐츠로 건너뛰기

네트워크 프로그래밍에서의 blocking, non-blocking, syncronous, asyncronous

출처 - http://devsw.tistory.com/142

TCP/IP 네트워크 프로그래밍 책을 보다보면 봉쇄(blocking), 비봉쇄(non-blocking), 동기(syncronous), 비동기(asyncronous)에 대해서 나옵니다. 이 개념에 대해 자세히 알아보려 합니다.

소켓 프로그래밍에서의 blocking
소켓 프로그래밍 책을 보다보면 read, write 함수를 가장 쉽게 보게 됩니다. 리눅스에서 read, write는 소켓 프로그래밍에서 패킷을 보내거나 받을때 사용하는 함수입니다. 이 함수는 소켓이 blocking이냐 non-blocking이냐 에 따라 작동방식이 살짝 다릅니다. 소켓이 blocking일 경우 Server 가 Client의 메시지 요청을 받기 위해 read에서 기다릴 수가 있습니다. Client가 write하기 전에는 read에서 빠져나오지를 못하는 것이지요. 

Blocking I/O 모델에서의 작동 방식 : 어플리케이션(프로그램)에서 recvfrom(read)를 호출 할 때, 커널은 데이터가 들어올 때까지 봉쇄(blocking)을 시킨다. 데이터가 들어오면 recvfrom(read)함수는 return이 되고, 프로그램 흐름은 어플리케이션(프로그램)으로 돌아온다.

소켓 프로그래밍에서의 non-blocking
위와 같이 blocking형태의 프로그래밍을 하다보면 서버 프로그램 입장에서는 여러 클라이언트의 처리가 어렵습니다. 그래서 나온 방법이 클라이언트 접속 별로 쓰레드를 생성하여 클라이언트별 read 함수를 호출 하는 것인데, 하지만 이 방법도 대규모 처리를 하기 위해서는 context switching에 발생하는 비용이 만만치 않아 프로그램의 성능을 떨어뜨립니다. 이러한 방법을 피할 수 있는 방법이 비봉쇄(non-blocking) 방법입니다. non-blocking은 위의 그림처럼 시스템함수 호출 후 멈출 필요가 없습니다. 읽을 데이터가 있으면 읽고, 없으면 넘어가게 되는 방법입니다.


Non-blocking I/O 모델에서의 작동 방식 : 어플리케이션(프로그램)에서 recvfrom(read)를 호출 할 때, 커널은 읽을 데이터가 없으면 EWOULDBLOCK(또는 EAGAIN, 둘의 의미는 똑같다.)을 return 한다.
위의 그림과 같이 소켓에 읽을 데이터가 있는지 없는지 recvfrom(read)을 loop 돌면서 계속 호출해주어야 합니다. (이 부분이 나중에 설명할 비동기 I/O와 살짝 다릅니다.)  이 방법은 결국 모든 소켓에 대한 체크를 해야하는 busy-waiting 상태가 됩니다. 리눅스에서는 적절한 sleep이 없는 loop는 100%의 CPU 점유율을 갖게 됩니다. 참고로 윈도우즈에서는 그런 현상이 없습니다.모든 소켓에 대해 확인을 할 수가 없어 사용하는 방법이 멀티 플렉스를 사용하는 것입니다. 리눅스 계열은 select, poll, epoll을 사용하게 됩니다. 즉, 이 기술들은 데이터 입출력에 직접적으로 필요한 기술이 아니라 파일디스크립터(소켓)을 관리하기 위한 것이라 보면 됩니다.

blocking과 non-blocking의 정리
여기까지 봉쇄(blocking), 비봉쇄(non-blocking)에 대해서 알아 봤습니다. 봉쇄와 비봉쇄의 차이점은  파일디스크립터 관련 함수에서 기다리냐 마느냐의 차이점입니다. 비봉쇄에서 read는 읽을 데이터가 없을 시 에러(-1)을 return을 하게 되어 errno.h의 errno을 확인하여 EWOULDBLOCK(또는 EAGAIN) 일 경우 적절한 처리를 해주어야 하기 때문에 프로그래밍이 조금 더 복잡해 질 수도 있습니다. 참고로 non-blocking 소켓으로 connect를 할 때에도 connect 함수가 에러를 return (-1) 할 수가 있습니다. 하지만 이것도 errno를 확인해보면 EINPROGRESS가 발생하는데 이 말은 즉, 연결요청이 진행중이다 라는 에러 입니다. 즉, '연결 완전 실패가 아닌 진행 중이지만 일단 에러로 return 하니 프로그래머가 알아서 처리를 하라' 라는 뜻입니다. 이렇듯 non-blocking 소켓 프로그래밍을 할 경우 에러처리를 톡톡히 해주어야 하는 단점이 있습니다. 하지만 에러처리를 잘하면 어떠한 빈틈도 없는 멋진 프로그램이 될 수도 있다는 뜻이지요.

동기(Syncronous)
이제 동기가 무엇인지 궁금해 졌습니다. 동기는 사실상 blocking과 차이점이 없다고 보시면 됩니다. "내(어플리케이션) 너(커널)의 작업(recvfrom)이 끝날 때 까지 기다려 줄께. 또는 시간을 맞춰줄께. 또는 동기화 해줄께" 라고 생각하시면 됩니다. 어플리케이션이 커널에 작업을 요청하고 커널에서 작업이 끝날때 까지 어플리케이션이 기다려 주는 것이지요. 즉, 동기화 하기 위해서 봉쇄(blocking)을 하는 것입니다. 그렇다면 비동기화(Asyncronous)하기 위해서 비봉쇄(non-blocking) 하는 것일 까요?

비동기(Asyncronous)
위에도 설명하였 듯이 비동기화 하기 위해 비봉쇄를 한다고 설명할 수 있을까요? 그렇다고 하기엔 내부적으로 작동하는 방법에 차이가 있습니다. 비동기의 간단한 개념을 따지자면 비동기 read함수를 호출하면 바로 return이 됩니다. 비동기 함수를 호출할 때는 작업이 완료가 될 때 알려줄 수 있는 event나 callback함수를 설정하게 됩니다. 즉, 어플리케이션이 커널에게 "읽을게 있으면 나에게 알려주던가(event) callback함수를 호출해~" 라고 하는 것입니다. 


Asyncronous I/O 모델에서의 작동 방식 : 어플리케이션(프로그램)에서 aio_read를 호출 할 때, 커널은 읽을 데이터가 있던 없던 return을 하게 되며, 읽을 데이터가 발생하게 되면 event를 발생하거나 callback함수를 호출하게 된다.
위의 그림과 같이 어플리케이션에서 aio_read를 호출하고 바로 return을 받게 됩니다. 커널은 데이터가 들어오면 event를 발생시키거나 callback함수를 호출하게 됩니다. 비동기 네트워크 프로그래밍을 할 때, event나 callback함수를 사용하게 됩니다. 즉, 비동기 프로그래밍은 non-blocking처럼 지속적인 관찰이 필요한 프로그래밍이 아니라 일단 작업을 걸어 두고 다른 작업을 진행한다가 어떠한 신호나 작업이 들어올 경우 걸어둔 작업을 진행한다. 라고 생각하시면 좀 더 수월해 질 것입니다.

마무리
비봉쇄(non-blocking)과 비동기(Asyncronous)는 다른 개념입니다. 특히 비동기 프로그래밍을 택한다면 소켓을 비봉쇄 소켓으로 만들면 안된다는 이야기가 있습니다. 제가 직접 테스트를 해본 것은 아니지만 stack overflow 사이트에서는 섞어서 사용하면 안된다고 나와 있네요. 아마도 커널 내부적으로 소켓이 blocking되어 작업이 끝나고 어플리케이션에 알려주어야 하는데 비봉쇄로 나와 버린다면 적업에 에러가 발생할 것 같습니다. 이부분에 대해서는 좀 더 연구가 필요하겠습니다.   

댓글

  1. 안녕하세요. 도움이 되는 글 감사합니다. 제가 완벽히 이해하지는 못한채 일단 비봉쇄 비동기 소켓 서버를 만들어서 구현을 해봤는데 작동은 됩니다만, 이게 권장되지 않는다는 건가요?? 제가 아직 확실히 몰라서 여쭤봅니다.

    답글삭제

댓글 쓰기

이 블로그의 인기 게시물

Baud Rate 와 Bit Rate 의 차이점

출처 - http://solvline.com/technical_info/tech_note_view.php?no=22&fno=&PHPSESSID=f5f096a5b1090ca017552de78745b8aa 1. Bit Rate 와 Baud Rate 의 정의 1.1 Bit Rate 정의 비트 레이트 (Bit Rate) 는 초당 얼마나 많은 데이터 비트 (‘1’ 또는 ‘ 0’) 를 전송할 수 있는가를 나타내는 말이다 . 또 우리가 자주 쓰는 BPS 라는 말이 있는데 이는 Bit Per Second 로서 초당 보낼 수 있는 비트의 수를 나타낸다 . 이는 모뎀의 전송속도를 측정하는 단위로 사용되어 졌다 . 일반적으로 28,800 모뎀이라면 28,800bps 의 전송속도를 나타내는 것이다 . 예를 들어 , 2400bit/second(bps) 라면 초당 2400 개의 비트 정보를 전달할 수 있다는 뜻이다 . 이는 반대로 이야기하면 1 비트 정보를 보내기 위해서 416.6us 의 시간 (1s/2400bit) 이 필요하다는 이야기이다 . 1.2 Baud Rate 보 레이트 (Baud Rate) 는 초당 얼마나 많은 심볼 (Symbol, 의미 있는 데이터 묶음 ) 을 전송할 수 있는가를 나타내는 말이다 . 이는 이론적인 통신 단위로 초당 신호 (Signal) 요소의 수 를 나타낸다 . 만약 하나의 신호요소가 2 비트로 구성되어 있는 경우라면 보는 BPS 의 반이 된다 . 즉 , 1 보 동안 2 비트가 전송된다 . 일반적으로 신호를 1 비트로 여긴다면 BPS 와 같은 단위가 된다 . 심볼이란 말은 의미 있는 데이터 비트의 묶음이다 . 일반적으로 시리얼 통신에서는 데이터 비트가 8-bit 를 사용하므로 이를 하나의 심볼이라고 이야기 할 수 있다 . 1 개의 symbol ( 또는 character) 는 8 개의 bit 정보와 같다 . 예를 들어 , 2400 baud rate 를 갖는다는 말은 1 초에 2400 개의...

시리얼(Serial) 이란?

출처 - http://www.ni.com/white-paper/2895/ko/#toc4 시리얼은 거의 모든 PC에서 표준으로 사용되는 디바이스 통신 프로토콜입니다. 시리얼의 개념을 USB의 개념과 잘 구분하십시오. 대부분의 컴퓨터에는 2개의 RS232 기반 시리얼 포트가 있습니다. 시리얼은 또한 여러가지 디바이스에서 계측을 위한 일반 통신 프로토콜이며, 여러 GPIB 호환 디바이스에는 RS232 포트가 장착되어 있습니다. 뿐만 아니라, 원격 샘플링 디바이스로 데이터 수집을 하는 경우에도 시리얼 통신을 사용할 수 있습니다. 시리얼 통신의 개념은 간단합니다. 시리얼 포트는 정보의 바이트를 한번에 한 비트씩 순차적으로 송수신합니다. 한번에 전체 바이트를 동시에 전달하는 병렬 통신과 비교하면 시리얼 통신은 속도가 느리지만 훨씬 간단하며 장거리에도 사용할 수 있습니다. 예를 들어, 병렬 통신용 IEEE 488 스펙을 보면 기기간 케이블링은 총 20 m 미만이어야 하며, 두 개의 디바이스간은 2 m 미만이어야 합니다. 반면 시리얼 통신은 최대 1.2 Km의 통신거리를 보장합니다. 통상 엔지니어들은 ASCII 데이터를 전송할 때 시리얼 통신을 사용합니다. 이 때 송신용 (Tx), 수신용 (Rx), 그라운드용 (GND)의 세 가지의 전송 라인을 사용하여 통신합니다. 시리얼은 비동기식이므로 포트는 한 라인에서 데이터를 전송하고 다른 라인에서 데이터를 수신합니다. 핸드쉐이킹용 라인도 사용 가능하지만 필수 요구사항은 아닙니다. 시리얼 통신의 가장 중요한 특징에는 보드 속도 (baud rate), 데이터 비트, 정지 비트, 패리티가 있습니다. 두 개의 포트가 통신하기 위해서는 이러한 파라미터가 반드시 적절하게 맞춰져야 합니다. 보드 속도는 통신의 속도를 측정하는 수치이며 초당 비트 전송 숫자로 표시됩니다. 예를 들어 300 보드 속도는 초당 300 비트를 의미합니다. 엔지니어들이 흔히 말하는 클럭 주기는 보드 속도를 의미합니다. 따라서 프로토콜에 ...

IR Cut Filter

R필터는 IR Cut off Filter, 적외선 차단 필터라고도 하며 이미지 센서라는 디지털 영상 장치의 핵심 부품의 작용 원리 때문에 필요한 부품임. 렌지를 통해 들어오는 빛은 일반적으로 인간의 눈으로 구별할 수 있는 가시광선 뿐 아니라 구별할 수 없는 적외선도 들어옴. 빛의 파장은 나노미터(nm)단위로 표시하는데 1nm는 10억분의 1미터, 즉 10-9승m로 이미지 센서는 가시광선 영역인 400~700nm뿐 아니라 근적외선 영역(~1150nm)까지 감지하여, 실제 색이나 화상하고는 관계없는 신호로 인해 영상의 선명도와 해상도가 떨어지므로 근적외선 영역의 파장들을 제거해 주기 위해 IR Cut off Filter가 필요함. 2. IR필터의 구조 및 제조과정 IR필터의 구조는 유리기판, 즉 D263과 같은 glass 위에 굴적률이 다른 두 가지 물질 Ti02, Si02 혹은 Ta205, Si02 같은 물질들을 교대로 증착시켜서 가시광선 영역은 투과하고 근적외선 영역은 반사시키는 구조임. IR터의 제조과정을 살펴보면 이들을 만드는 데 있어서 핵심기술은 진공박막증착 기술이며, 이는 유리 기판에 굴절률이 서로 다른 2가지 물질, Ti02/Si02혹은 Ta205/Si02을 교대로 증착시켜서 (30~40층) 가시광선 영역을 투과하고 근적외선 영역은 반사시키는 광학필터를 만드는 것임.  과거에는 유리 기판 대신에 LCD유리를 많이 사용했으나 최근 화소스가 증가하면서 규격이 높아져서 D263이라는 양면 연마된 유리 기판들이 많이 쓰이고 있음. 이들 제품은 우선 투과 및 반사대역이 원하는 파장대역과 맞는가 하는 점과 표면에 일정 크기 이상의 이물들이 없는 가의 평가법을 통한 평가를 통해 제잭된 필터 원파(보통 127X127mm)을 필요한 크기로 잘라서 CCD나 CMOS등의 이미지 센서 앞에서 장착하게 됨. 3. IR필터 응용분야 IR필터는 주로 디지털 카메라, 캠코더, CCTY용 카메라, 적외선 감시카메라, 차량용 후방감시 카메라 등 다양한 분야에 사용되나 최근 이...