1. 블로킹 함수(blocking function)란?
디바이스에 처리 요청을 걸어 놓고 응답을 대기하는 함수를 일컫는다. 그리고 해당 블로킹 함수를 호출할 때 스레드에서 발생하는 대기 현상을 블로킹이라고 한다. 소켓뿐만 아니라 파일 핸들에 대한 함수를 호출했을 때도 이러한 대기 현상이 발생하는 것을 모두 블로킹이라고 한다.
[https://thebook.io/006884/0172/]
요청이 동시다발적으로 들어오는 대규모 서버에서 블로킹 함수의 호출이 발생한다면 큰 지연과 성능저하가 발생할 것이다. 하지만 블로킹 함수는 공유 자원에 대한 접근을 제한해 잘못된 데이터 수정/접근을 막는데 필수 불가결한 존재이다.
따라서 좋은 서버, 프로그램을 만들기 위해서는 blocking / non-blocking의 개념을 잘 알아야 하며 같이 자주 쓰이는 Synchronous와 Asynchronous의 개념 또한 알아야 한다.
2. 논 블로킹 vs 블로킹(non-blocking vs blocking)
블로킹과 논블로킹을 구분할 때는 함수의 제어권을 인식하고 접근하는 것이 좋다. 블로킹 방식은 함수 수행의 제어권을 호출한 함수에게 완전히 넘겨주는 방식으로 함수 종료까지 다른 일을 수행하지 못하고 기다린다.
그에 반해 논블로킹 방식은 수행의 제어권을 호출한 함수에게 넘겨주자마자 제어권을 callback으로 다시 넘겨 받으면서 다른 일을 수행할 수 있게 된다.
Blocking (블로킹): 블로킹은 어떤 작업이 완료될 때까지 프로그램이 대기하는 것을 의미한다. 예를 들어, 데이터를 읽을 때 블로킹 방식을 사용하면 데이터가 도착할 때까지 대기한다.
Non-Blocking (논블로킹): 논블로킹은 작업이 완료되지 않아도 다른 작업을 진행할 수 있는 방식이다. 데이터가 도착하지 않아도 프로그램은 다른 작업을 수행하며, 나중에 도착한 데이터를 처리한다.
[ 서버측에서 블로킹은 특정 작업이 끝날 때까지 서버가 다른 요청을 처리하지 못하게 하는 것이며, 논블로킹은 여러 작업을 동시에 처리하면서 완료된 작업에 대한 처리를 순차적으로 하는 방식이다. ]
3. 동기 vs 비동기(Synchronous vs Asynchronous)
동기/비동기 방식은 작업의 진행 방식이라고 생각하고 접근하는 것이 좋다. 프로세스, 스레드, 서버 등등...에서 작업이 이루어 진다고 가정하자. 이 때, 한 프로세스 내부에서 서로 다른 기능을 하는 독립적인 두 스레드가 동시에 실행되고 있다. 그렇다면 두 스레드는 비동기인가? 답은 아니다. 두 스레드가 서로의 결과값을 통해 영향을 주고 받을 때만 비동기라고 볼 수 있다.
Synchronous(동기): 동기 방식은 요청한 작업이 완료될 때까지 대기하는 방식이다. 즉, 작업이 시작되면 해당 작업이 완료될 때까지 다음 작업으로 진행하지 않는다.
Asynchronous(비동기): 비동기 방식은 작업을 요청한 후에도 다음 작업을 진행할 수 있는 방식이다. 작업이 완료되기를 기다리지 않고 다른 작업을 수행하다가, 완료 시 콜백이나 알림을 통해 처리 결과를 받아온다.
[ 서버에서는 주로 비동기 방식을 사용하여 여러 작업을 동시에 처리한다. 이는 다수의 클라이언트 요청을 효율적으로 처리하는 데 도움이 된다. ]
Blocking / Non - Blocking은 기술(함수의 제어권 등)을 통해 명확한 구분을 할 수 있다. 그러나 Synchronous / Asynchronous 은 인과관계만 있다면 성립될 수 있는 개념이므로, 추상적으로만 구분이 가능하다. |
4. 동기 / 비동기 & 블로킹 / 논블로킹
+) 앞서 3, 4번에서 소개한 개념을 조합한다면 위 4가지의 조합을 만들 수 있다. 그러나, 위 4가지 조합을 조사하면서, 왜 비효율적인 Async - blocking 방식을 사용하는 건지 궁금하여 구글링을 하던 중 아래 evan-moon 님의 포스팅을 읽게 되었다. 현재 Application 단계에서는 거의 사용하지 않고 저수준의 서버 I/O 을 처리하는 특수한 상황에 사용한다는 사실을 추가적으로 알게 되었다. 아래 글을 꼭 읽어보기를 바라는 맘으로 출처를 남긴다.
https://evan-moon.github.io/2019/09/19/sync-async-blocking-non-blocking/
동기(Synchronous)는 정확히 무엇을 의미하는걸까?
이번 포스팅에서는 I/O와 네트워크 등 전반적으로 다양한 모델에서 사용하는 개념인 가 정확히 무엇을 의미하는 것인지, 그리고 동기 방식과 비동기 방식의 차이에 대해서 한번 이야기 해보려고
evan-moon.github.io
5. Overlapped 란?
Non-Blocking방식으로 동작하는 비동기 I/O 처리 방법이다. 중첩 입출력 방식 또는 비동기 입출력(Asynchronous I/O) 방식이라고도 부른다. 소켓은 기본적으로 Blocking / sync 방식으로 만들어 진다. 그러나 해당 방식으로는 단일 스레드에서 두 개 이상의 소켓을 다루기 힘들다. 이 방식을 바꾸지 않고 여러 개의 소켓을 처리하려면 멀티스레드 기술을 사용해야 한다. 그러나, 다중 스레드에서 비동기 I/O를 사용한다면 스레드 간 작업 순서의 문제로 deadlock 등의 현상이 발생할 수 있다. 따라서 단일 스레드에서 Overlapped I/O 방식을 사용한다면 자원 문제, Blocking 문제 없이 I/O를 처리할 수 있다.
[https://1d1cblog.tistory.com/385]
+) 작업자 스레드란?
작업자 스레드는 주로 병렬 처리를 위해 사용되는 스레드이다. 주로 멀티스레딩 환경에서 작업을 분산하고 병렬로 수행하기 위해 동작하는 스레드를 일컫는 말이다.
6. IOCP 란?
Window 환경에서 작동하는 제일 흔하게 쓰이는 논블로킹 프로세스이다. IOCP는 IO Completion Port의 약자로, 입출력 완료 포트라고 부른다. 입력과 출력의 완료를 담당할 포트를 정해서 작업을 처리하는 것인데, overlapped 모델에서 처리가 되므로, overlapped 모델의 확장판이라고 보면 될 것이다. 주로 서버 애플리케이션에서 사용되고, 다수의 클라이언트와의 동시 통신에 유용하다.
'자유게시판' 카테고리의 다른 글
[IMS 스터디] 게임 서버 스터디 <2주차> (0) | 2024.02.02 |
---|---|
항해 플러스 코육대) 총알 피하기 참가 후기! (0) | 2023.10.03 |