Blocking/Non-blocking & Synchronous/Asynchronous
동기 / 비동기
동기 작업이란
작업을 수행하는 두 개 이상의 주체가 서로 동시에 수행하거나, 동시에 끝나거나, 끝나는 동시에 시작할 때를 의미합니다. 시작과 종료를 동시에 하거나, 하나의 작업이 끝나는 동시에 다른 주체가 작업을 시작하면 이는 동기 작업이라고 볼 수 있습니다.
비동기 작업이란
두 주체가 서로의 시작, 종료시간과는 관계 없이 별도의 수행 시작/종료시간을 가지고 있을 때를 뜻합니다. 서로 다른 주체가 하는 작업이 자신의 작업 시작, 종료시간과는 관계가 없을 때 비동기라고 부를 수 있습니다.
블로킹 / 논블로킹
블로킹과 논블로킹은 다른 작업을 수행하는 주체를 어떻게 상대하는지가 중요하다.
자신의 작업을 하다가 다른 작업주체가 하는 작업의 시작부터 끝까지 기다렸다가 다시 자신의 작업을 시작한다면 이는 블로킹이고, 다른 주체의 작업과 관계없이 작업을 계속한다면 이를 논블로킹이라고 할 수 있다.
스레드 A가 어떤 작업을 하는 대상을 호출하고, 그 대상이 가져온 결과물을 받아 다시 작업을 재개하고있다.
예를 들자면 java에서 jdbc를 사용하여 DB에 질의를 날리고 결과를 받아오는 작어블 블로킹 작업이라고 부를 수 있습니다. 이와 반대로 다른 주체에게 작업을 요청하고 그 결과를 받을 때가지 기다리지 않으며 작업을 한다면 이를 논블로킹이라고 할 수 있습니다.
동기/비동기와 블로킹/논블로킹의 조합
Blocking I/O & Non-Blocking I/O
1. Blocking I/O
I/O Blocking 형태의 작업은
(1) Process(Thread)가 Kernel에게 I/O를 요청하는 함수를 호출
(2) Kernel이 작업을 완료하면 작업 결과를 반환 받음.
- 특징
- I/O 작업이 진행되는 동안 user Process(Thread) 는 자신의 작업을 중단한 채 대기
- Resource 낭비가 심함
(I/O 작업이 CPU 자원을 거의 쓰지 않으므로)
여러 Client 가 접속하는 서버를 Blocking 방식으로 구현하는 경우 -> I/O 작업을 진행하는 작업을 중지 -> 다른 Client가 진행중인 작업을 중지하면 안되므로, client 별로 별도의 Thread를 생성해야 함 -> 접속자 수가 매우 많아짐
이로 인해, 많아진 Threads 로 컨텍스트 스위칭 횟수가 증가함,,, 비효율적인 동작 방식
2. Non-Blocking I/O
I/O 작업이 진행되는 동안 User Process의 작업을 중단하지 않음.
- 진행 순서
- User Process가 recvfrom 함수 호출 (커널에게 해당 Socket으로부터 data를 받고 싶다고 요청함)
- Kernel은 이 요청에 대해서, 곧바로 recvBuffer를 채워서 보내지 못하므로, "EWOULDBLOCK"을 return함.
- Blocking 방식과 달리, User Process는 다른 작업을 진행할 수 있음.
- recvBuffer에 user가 받을 수 있는 데이터가 있는 경우, Buffer로부터 데이터를 복사하여 받아옴.
- 이때, recvBuffer는 Kernel이 가지고 있는 메모리에 적재되어 있으므로, Memory간 복사로 인해, I/O보다 훨씬 빠른 속도로 data를 받아올 수 있음.
- recvfrom 함수는 빠른 속도로 data를 복사한 후, 복사한 data의 길이와 함께 반환함.