이번 시간에는 블로킹과 논블로킹에 대해서 간단하게 알아보도록 하겠습니다.

 


 아래 코드를 생각해 보겠습니다.

 

 문자열을 입력받고, 출력해 주는 프로그램입니다. 중요한 것은, 이 프로그램은, 제가 아무것도 입력을 하지 않으면, 입력을 받을 때 까지 대기를 한다는 것입니다. 더 정확하게 말하면, 엔터나 EOF가 들어올 때 까지 계속 입력을 받습니다. 이를 특정한 Event라고 칭하겠습니다. 이 프로그램의 순서도는 아래와 같이 그릴 수 있습니다.

 

 

 이 중에서 fgets만 확대해서 그려보겠습니다. Main에서 fgets를 호출했기 때문에 Main은 caller가 되고, fgets는 Main에 의해 불려진 함수가 될 거에요.

 

 

 그러면, 이 경우에는 Main으로 제어권이 넘어오지 않을 거에요. 즉, Main은 block이 된 상태입니다. 제어권을 가지고 있지 않기 때문이에요.

 

 

 'a'가 입력되었습니다. 그럼에도, 제어권은 Main이 가지고 있지 않아요. 왜냐하면, 특정한 Event가 발생하지 않았기 때문입니다.

 

 

 '\n'이 입력되었습니다. 개행 문자가 입력되는 것은, fgets의 특정 Event입니다. 그러면 이 때, 다음과 같은 일이 일어납니다.

 

 

 프로그램의 흐름도는 위와 같습니다. 대략적으로 보면, 위와 같은데요. Main 함수에서의 fgets(str,100,stdin);은, '\n'이나 EOF가 입력이 받을 때 까지, 끝나지 않았습니다. 그 때 까지 수행이 되지 않았으므로, block이 되었다고 할 수 있습니다.

 

 

 즉, 그 동안은 제어권이 Main에 있지 않다는 것입니다. 반면에 non block은 이야기가 다릅니다.

 

 


 wait 함수랑 waitpid 함수를 제가 언제 한 번 썼었습니다. 이 중 wait 함수는, 부모가 생성한 child process가 끝날 때 까지 리턴을 하지 않는, 블로킹 함수입니다.

 

 

 반면에, waitpid에 WNOHANG 옵션을 주면, Target 프로세스가 종료되지 않았다고 해도, 바로 값을 리턴해 버립니다.

 

 

 즉, 특정한 이벤트가 발생할 때 까지 blocking이 되는 것과 달리, 그냥 값만 리턴하고 빠져나옵니다. 분명한 것은 Target Process가 종료되는 이벤트는 '오래 걸릴 수도 있는' 것 중 하나입니다. 그럼에도 특정한 값을 리턴해 버리고 제어권을 Main에게 바로 넘겨주었습니다. 이를 논블로킹이라고 이야기 합니다. 그러면, 그 특정한 child가 종료될 때 프로그램이 끝나려면 어떻게 하면 될까요?

 

 

 이 함수는 WNOHANG을 넘겼을 때, child가 Terminate가 되었을 때와, 그렇지 않을 때 다른 값을 리턴합니다. Target이 Terminate가 되지 않았을 때에는 0을 리턴하는데요. 이를 이용해서 아래와 같은 코드를 작성할 수 있습니다.

 

 

 이런 식으로요. 아마, sleep sort를 보신 분들은 이것이 어떤 코드인지는 대략적으로 아실 수 있을 듯 싶습니다.