블록킹, 넌블록킹, 동기, 비동기
블록킹(Block), 넌블록킹(Non-Block), 동기(Synchronous), 비동기(Asynchronous)에 대한 개념들은 I/O 작업, 특히 네트워크 통신에서 자주 마주치게 되며, 애플리케이션의 효율성과 성능을 결정하는 중요한 요소가 됩니다. 이 네 가지 I/O 방식에 대해서 알아봅시다.
블록킹(Block) vs 넌블록킹(Non-Block)
블록킹과 넌블록킹은 프로세스 또는 스레드가 I/O 작업을 수행할 때의 동작 방식을 기술하는 용어입니다.
블록킹(Block)
출처 : https://www.beningo.com/embedded-basics-blocking-vs-non-blocking-drivers
- 블록킹 I/O 작업을 시작한 프로세스(또는 스레드)는 해당 작업이 완료될 때까지 대기하게 됩니다. 따라서 블록킹 연산은 호출한 스레드를 블록 상태로 만듭니다. 이때 블록 상태란 CPU가 해당 스레드를 실행하지 않는 상태를 말합니다. 블록킹 연산이 완료되면, 스레드는 다시 실행 가능 상태가 됩니다.
넌블록킹(Non-Block)
출처 : https://www.beningo.com/embedded-basics-blocking-vs-non-blocking-drivers
- 넌블록킹 I/O 작업을 시작한 프로세스(또는 스레드)는 해당 작업이 완료되길 기다리지 않고 바로 다음 작업을 진행할 수 있습니다. 즉, I/O 작업이 실행 중인 상태에서도 다른 연산을 수행할 수 있는 것입니다. 넌블록킹 방식은 I/O 작업이 CPU 작업에 비해 상대적으로 느릴 때 효과적입니다.
- 예를 들어, 네트워크 요청이나 디스크 읽기와 같은 작업은 CPU 연산에 비해 상당히 오래 걸리므로, 이러한 작업을 수행하는 동안 다른 작업을 진행할 수 있도록 하는 것이 효율적일 수 있습니다.
동기(Synchronous) vs 비동기(Asynchronous)
동기와 비동기는 작업의 순서 또는 작업 간의 시간 관계를 기술하는 데 사용되는 용어입니다.
동기(Synchronous)
- 동기 작업은 어떤 작업이 끝나야만 다음 작업을 시작할 수 있습니다. 즉, 동기 방식은 작업이 순차적으로 실행되어야 하며, 한 작업이 완료되지 않으면 다음 작업이 시작되지 않습니다.
비동기(Asynchronous)
- 반면에 비동기 작업은 작업 간에 서로 독립적입니다. 즉, 한 작업이 완료되지 않아도 다른 작업이 시작될 수 있습니다. 비동기 방식은 여러 작업을 병렬로 실행할 수 있으므로, 효율성과 성능 향상에 도움이 될 수 있습니다.
블록킹 vs 넌블록킹, 동기 vs 비동기
출처 : http://homoefficio.github.io/2017/02/19/Blocking-NonBlocking-Synchronous-Asynchronous/
블록킹과 넌블록킹은 I/O 작업의 동작 방식을 기술하고, 동기와 비동기는 작업의 순서나 시간 관계를 기술합니다. 이 두 세트의 개념은 서로 독립적입니다. 즉, 블록킹 작업이 동기적일 수도 있고 비동기적일 수도 있습니다. 마찬가지로, 넌블록킹 작업이 동기적일 수도 있고 비동기적일 수도 있습니다.
예를 들어, 블록킹 동기 작업은 작업이 완료될 때까지 대기하고, 작업이 완료된 후에만 다음 작업을 시작합니다. 반면에, 블록킹 비동기 작업은 작업이 완료될 때까지 대기하지만, 다른 작업이 동시에 진행될 수 있습니다.
넌블록킹 동기 작업은 작업을 시작하고 즉시 다음 작업으로 넘어갑니다. 그러나 작업은 순차적으로 수행되며, 이전 작업이 완료될 때까지 다음 작업을 시작하지 않습니다. 넌블록킹 비동기 작업은 작업을 시작하고 즉시 다음 작업으로 넘어갑니다. 또한, 작업은 동시에 실행되며, 이전 작업의 완료를 기다리지 않고 다음 작업을 시작할 수 있습니다.
실제 예시를 통한 이해
동기 & 블록킹
- 대부분의 시스템 호출은 동기 블록킹 방식으로 동작합니다. 예를 들어, 파일을 읽어올 때
read()
함수를 사용하는데 이 함수는 동기 블록킹 I/O 함수입니다. 따라서 이 함수를 호출하면 해당 함수는 파일의 내용이 읽혀질 때까지 블록 상태가 됩니다.- 이 방식은 코드가 간결하고 이해하기 쉬운 편이지만, 대량의 요청 처리나 병렬 처리에는 적합하지 않습니다.
동기 & 넌블록킹
- 동기 넌블록킹의 예로는 투표방식(polling)이 있습니다. 프로그램은 데이터가 준비되었는지 아닌지 계속 확인하며, 데이터가 준비되었을 때만 받아옵니다.
- 이 방식은 다수의 연결을 동시에 처리할 수 있지만, 각 소켓을 계속해서 체크해야 하기 때문에 CPU 자원을 많이 사용하게 됩니다. 따라서 효율적이지 못하다는 단점이 있습니다.
비동기 & 블록킹
- 비동기 블록킹은 상대적으로 흔하게 사용되지는 않지만, 이런 방식을 사용하는 경우도 있습니다. 예를 들어, 다중 스레드를 사용하는 경우에는 각 스레드에서 블록킹 I/O 작업을 수행하면서도 다른 스레드에서는 다른 작업을 계속 진행하는, 비동기 블록킹 방식이라고 볼 수 있습니다.
- 이 방식은 멀티스레드 관리의 복잡성이 증가하는 단점이 있습니다.
비동기 & 넌블록킹
- 비동기 넌블록킹 방식은 이벤트 드리븐 프로그래밍에 사용됩니다. Node.js의 콜백 패턴이나 Java의 NIO, Python의 asyncio 등이 이 방식을 사용합니다. I/O 작업 완료를 알림을 받아 처리하는 콜백 함수를 등록하고, 이벤트 루프를 통해 여러 I/O 작업을 동시에 처리합니다.
- 이 방식은 많은 요청을 동시에 처리하는 데 효율적입니다.
Comments powered by Disqus.