[OS] 동기 vs 비동기, 블로킹 vs 논블로킹
이번 포스팅에서는 동기와 비동기, 블로킹과 논블로킹에 대해서 알아보도록 하겠습니다.
네 단어 모두 익숙하지만 명확하게 설명할 수 없고 이해가 부족하다는 생각이 들어서 정리해보았습니다.
Synchoronous VS Asynchoronous, Blocking VS Non-blocking
각 개념을 설명하는데 아래의 그림이 가장 일반적입니다. 4가지로 나눠서 하나씩 알아보도록 하겠습니다.
Synchoronous-Blocking
가장 일반적인 상황입니다. Application은 Kernel에 System call을 하고 응답이 올 때 까지 기다리게 됩니다. (Synchoronous) 그리고 Kernel은 I/O 작업을 다 한 후에 Application에 응답을 보냅니다. (Blocking)
그렇기 때문에 Application은 Kernel에게 System call을 보낸 시점부터 다시 응답을 받기까지 아무런 작업을 못한 체 대기를 하게 됩니다.
Synchoronous-Non-blocking
위와 마찬가지로 Application은 Kernel에 System call을 하고 응답이 올 때 까지 기다리게 됩니다. 하지만 Kernel에서의 동작이 바뀌었습니다. I/O 작업이 끝나지 않았음에도 Application에게 아직 완료되지 않았다는 EAGAIN or EWOULDBOLCK을 응답합니다.
EAGAIN : 아직 데이터가 없으니 이후 다시 시도하라는 의미입니다.
EWOULDBOLCK : 송신시 소켓 송신 버퍼가 꽉 찼거나 수신시 소켓 수신 버퍼가 비어 있음을 의미합니다.
그 후 Application은 Kernel이 작업을 마쳤는지 확인하기 위해 계속 System call을 하고 이 과정에서 context switching이 빈번하게 발생하여 비효율적으로 동작하게 됩니다.
Asynchoronous-blocking
Application은 System call을 하고 해당 처리에 대해 관심이 없고 다른 일을 하고 싶어하지만 Kernel에서 blocking을 걸기 때문에 다른 일을 할 수가 없습니다.
select()
를 사용하여 모니터링하고 I/O 작업이 끝날 때까지 기다립니다.
Asynchoronous-Non-blocking
Application은 Kernel에 System call을 하고 응답이 올 때 까지 기다리지 않습니다. 또한 Kernel에서도 Non-blocking이므로 Application이 다른 일을 하도록 내버려둡니다.
Application은 다른 일을 할 수 있게 되는 것이죠.
정리
이번 포스팅에서 살펴봤던 네 단어를 다음과 같이 정리할 수 있습니다.
용어 | 설명 |
---|---|
Synchoronous | 동기, 즉 동시에 일어나기 위해서는 호출된 함수의 결과값을 호출한 함수가 기다립니다. |
Asynchoronous | 비동기, 동시에 일어나지 않아도 상관이 없습니다. 따라서 호출된 함수의 결과값을 호출한 함수가 신경쓰지 않습니다. (Callback함수로 처리를 합니다.) |
Blocking | 블로킹은 스포츠 경기에서도 많이 사용되는 용어죠. 농구에서도 상대방의 슛을 가로막는 것을 의미합니다. 제어권을 호출된 함수가 가지고 있어 호출된 함수가 호출한 함수를 막고 있는 겁니다. |
Non-blocking | 호출된 함수가 자신의 일의 종료와는 상관없이 제어권을 호출한 함수에게 넘겨줍니다. |
참조
https://developer.ibm.com/technologies/linux/articles/l-async/