SSISO Community

시소당

소켓의 넌블럭킹 (non-blocking) 모드란...

꽤  어려운  주젠데..

특히  운영체제의  핵심인  커널관련  내용의  설명이  반드시  필요한  주제라..
글쓰기를  망설였는데...ㅇㅇ;
다  쓰고  나서  읽어봐도  역시나  좀  어려운  내용이  되버렸군요  ㅇㅇ;


자세한  내용은  [스티븐]  씨의  책을  참조하세요
(멋진  그림도  많음  ㅇㅇ;)


우선  nonblocking  i/o  이  어떻게  동작하는지에  들어가기전에
몇가지  개념부터  알아야  합니다.

1.  블럭된다는  말의  뜻은?
      프로세스  는  상태를  가지고  있다는  말을  들어봤을텐데..ㅇㅇ
      실행가능상태,  sleep  상태,  ..........등등
      여기서  실행가능상태가  아니다  라는게  블럭의  뜻입니다.
      (어떤  이벤트가  발생하면  실행가능  상태로  전환됨)
      (즉,  프로세스  스케쥴링이  안됨  )

2.  커널주소공간  과  사용자주소  공간이란..?
      주소공간이란  것의  느낌처럼,  메모리의  일부죠.
        헌데,  커널주소공간은  커널만  접근가능하고(=  cpu  의  커널모드상태),
        사용자  주소공간은  해당  프로세스만  접근가능하죠.(=  cpu  의  사용자모드  상태)
      이것은  cpu  차원에서  지원해주는  기능을  이용하죠.

      커널모드상태와  사용자모드상태  사이의  전환은  인터럽트에  의해서만  가능하답니다.
      시스템콜도  인터럽트를  사용해서  들어가게  되는데...
      다시말해  php  에서  fopen()  을  호출하면  php  는
      표준라이브러리의  open()  래퍼함수를  호출하고,  이  래퍼함수는  시스템콜을  호출하죠
      즉,  라이브러리가  제공하는  래퍼함수를  통해
      커널모드상태로(시스템콜은  이  상태에서만  실행가능)  들어갑니다.

3.  blocking  i/o  소켓에서  gets()  할떄  어떤  동작이  이뤄지나?
      크게  두부분으로  나눠지는데..
      첫쨰,  데이터가  준비되기전까지  블럭됨(기다리게됨)
      둘쨰,  데이터가  커널주소공간  에서  사용자공간주소로  복사됨(위에  애기했죠?  ㅇㅇ)
                      (즉,  지금실행중인  프로세스가  접근가능한  주소공간으로  데이터를  복사한다는
                      말이죠..그래야  우리가  이  데이터에  접근가능하니까..)

      
이제    넌블럭킹이  어떻게  동작하는지  보죠..
사실,  i/o  방법은  블럭킹/넌블럭킹  말고도  여러  종류가  있습니다.
크게  i/o  방법을...두가지로  구분하죠

1)  asynchronous  i/o  (비동기  i/o)  :  전혀  블럭킹안됨
                                                                                                    fgets()  호출과  동시에  리턴이  되버리며,
                                                                                                    커널이  데이터가  준비되고  이데이터가
                                                                                                    커널주소공간에서  사용자주소공간으로  복사가  완료되면
                                                                                                    즉,  모든게  준비되면
                                                                                                    프로세스에게  signal(신호)  를  보냅니다.
                                                                                                    (따라서,  프로세스는  이  신호를  처리할  핸들러를
                                                                                                    만들어줘야  합니다.)

2)  synchronous  i/o  (동기  i/o)    :  위에서  사전지식중  3  부분에서  애기한
                                                                                            gets()  의  첫째나  둘째  중에서  반드시  블럭킹이  발생합니다.

넌블럭킹은  2)  synchronous  i/o  카테고리에  해당하는  i/o  방법이죠

블럭킹과  넌블럭킹을  그럼  비교해보죠.
아래설명은  위의  사전지식  3번째  부분의  첫째  둘쨰  항목을  대상으로  합니다.

1)  블럭킹  :  데이터가  준비되기를  기다리는  부분과  커널주소공간에서  사용자주소공간으로
                              데이터를  복사하는  부분  둘  모두가  완전히  끝날떄까지
                              프로세스가  [실행불가능]  상태로  계속  머무르는  걸  말합니다.

                              이제서야  리턴되죠..그러면  내  작업은  계속  진행될테고요..ㅇㅇ

2)  넌블럭킹  :  데이터가  준비되기를  기다리는  첫번쨰  단계에서  블럭되는게  아니라
                                      무저건  리턴되버립니다.(즉,  우리작업이  계속됨.)
                                      소켓에서  받아온  데이터를  사용하기위해서는...
                                      for  같은  루프  안에서  fgets()  함수를  계속  콜해서
                                    데이터를  일일이  얻어야  합니다.

                                    즉,  polling  이죠.
                                      예를들어,  php  로  채팅기능을  구현할떄
                                      meta  태그로  1  초간격으로  refresh  를  계속하는것처럼요..

                                    앞에서  애기했다시피  이  방법이  동기  i/o  에  속하기때문에
                                    블럭킹이  되는  부분이  있는데..
                                  바로  커널주소공간에서  사용자주소  공간으로  데이터  복사할때
                                (즉,  내가  사용할  데이터가  준비됀  후에야  작업이  가능하므로..)
                                  블럭킹이  됩니다.


과연  이  넌블럭킹  방법을  어디에  사용하는게  좋을까요?
이것또한  스티븐  님의  책을  보거나  문서를  참조하세요~
웹페이지  다운로드  예를들면서  블럭킹과  넌블럭킹  사용의  잇점  단점을  잘  보여줍니다.

7166 view

4.0 stars