본문 바로가기

Backend study/Backend theory

Blocking과 Non-blocking

BlockingNon-blocking은 프로그램이나 시스템에서 작업이 완료될 때까지 대기하는지 여부에 대한 중요한 개념이다. 이 두 개념은 주로 I/O(입출력) 작업, 스레드, 네트워크 통신과 같은 상황에서 사용된다. 이 개념들을 이해하는 것은 프로그램의 성능, 응답성, 자원 사용에 큰 영향을 미치기 때문에 중요하다.

 

1. Blocking (블로킹)

Blocking이란?

  • Blocking어떤 작업이 완료될 때까지 해당 작업이 끝날 때까지 프로세스나 스레드가 대기하는 방식을 의미한다. 작업이 완료되기 전까지 다른 작업을 수행하지 않고, 해당 작업이 끝난 후에야 다음 작업으로 넘어갈 수 있다.
  • 보통 입력이나 출력(I/O) 작업에서 많이 사용되며, 네트워크 통신, 파일 시스템 접근, 스레드 동기화 등 다양한 상황에서 Blocking 방식이 사용된다.

Blocking의 특징

  • 작업 대기: 블로킹 호출을 하는 동안 해당 호출이 완료될 때까지 작업이 중단된다. 예를 들어, 파일을 읽는 작업이 완료될 때까지 프로그램은 파일이 모두 읽힐 때까지 대기한다.
  • 간단한 구현: 블로킹 방식은 프로그래밍이 간단하고 직관적이다. 작업이 완료될 때까지 대기하므로, 다음 작업을 언제 시작해야 하는지 고민할 필요가 없다.
  • 성능 저하 가능성: 네트워크 요청이나 파일 읽기/쓰기 같은 작업은 시간이 오래 걸릴 수 있기 때문에, 블로킹 방식은 프로그램의 응답성을 저하시킬 수 있다. 특히, 사용자 인터페이스(UI)를 차단하는 경우 프로그램이 "멈춘" 것처럼 보일 수 있다.

Blocking의 예시

다음은 Python에서 블로킹 I/O 작업의 예시이다. 네트워크 소켓에서 데이터를 읽을 때, 소켓으로부터 데이터를 받을 때까지 대기하는 동작이다.

import socket

# 서버에 연결
s = socket.socket()
s.connect(('example.com', 80))

# 서버로부터 데이터 받기 (blocking)
data = s.recv(1024)  # 데이터가 올 때까지 기다림

print("Received:", data)

위의 코드에서 s.recv(1024)는 서버로부터 1024바이트의 데이터를 받을 때까지 차단(Blocking) 된다. 서버가 응답을 보낼 때까지 프로그램은 대기하고, 그 동안 다른 작업은 수행되지 않는다.

Blocking의 장점과 단점

  • 장점:
    • 구현이 간단하고 이해하기 쉽다.
    • 순차적으로 실행되므로 프로그램의 흐름을 예측하기가 용이하다.
  • 단점:
    • 대기 시간이 길어질 경우 성능이 저하될 수 있다.
    • 특히 네트워크나 파일 I/O 작업에서 대기 시간이 길어지면, 전체 프로그램의 응답성이 낮아진다.
    • 멀티스레드 환경에서, 하나의 스레드가 블로킹 상태일 경우 다른 스레드도 영향을 받을 수 있다.
    •  

2. Non-blocking (논블로킹)

Non-blocking이란?

  • Non-blocking작업이 즉시 완료되지 않더라도, 프로세스나 스레드가 해당 작업을 기다리지 않고 바로 다음 작업으로 넘어가는 방식을 의미한다. 즉, 작업을 요청한 후 작업이 완료되기를 기다리지 않고, 즉각적으로 다른 작업을 수행할 수 있다.
  • 비동기적(Asynchronous) 작업 처리 방식과 관련이 있으며, 프로그램의 응답성을 높이기 위한 중요한 기법이다.

Non-blocking의 특징

  • 즉시 반환: Non-blocking 호출은 결과가 준비되지 않은 경우에도 즉시 반환된다. 작업이 완료되지 않았더라도, 다른 작업을 계속 진행할 수 있다.
  • 다른 작업 병행 가능: Non-blocking 방식에서는 대기하는 대신 다른 작업을 계속할 수 있으므로, 여러 작업이 동시에 이루어질 수 있는 장점이 있다.
  • 복잡한 제어 흐름: Non-blocking 방식은 블로킹 방식보다 코드가 복잡할 수 있다. 작업의 완료 시점을 직접 관리해야 하며, 이를 위해 콜백 함수나 이벤트 루프를 사용하는 경우가 많다.

Non-blocking의 예시

다음은 Python에서 Non-blocking 소켓 작업의 예시이다. 소켓을 논블로킹 모드로 설정하여 데이터를 기다리지 않고, 작업을 계속 진행한다.

import socket

# 서버에 연결
s = socket.socket()
s.setblocking(False)  # 논블로킹 모드로 설정
try:
    s.connect(('example.com', 80))
except BlockingIOError:
    # 연결이 완료되지 않았더라도 다른 작업을 계속 수행
    pass

# 다른 작업을 수행하는 동안 데이터가 준비될 때까지 대기하지 않음
try:
    data = s.recv(1024)  # 데이터가 아직 준비되지 않았을 수 있음
    print("Received:", data)
except BlockingIOError:
    # 데이터가 아직 준비되지 않았으면 즉시 반환
    print("No data available")

위의 코드에서 s.setblocking(False)를 사용하여 소켓을 Non-blocking 모드로 설정한다. 이로 인해 s.recv(1024)는 데이터가 없을 경우 즉시 반환되며, 프로그램이 계속 실행된다. 즉, 데이터를 기다리며 멈추지 않고 다른 작업을 처리할 수 있다.

Non-blocking의 장점과 단점

  • 장점:
    • 프로그램의 응답성이 높아진다. 하나의 작업을 기다리지 않고 다른 작업을 처리할 수 있다.
    • 멀티태스킹에 유리하며, 특히 네트워크 통신이나 파일 I/O 작업에서 유용하다.
    • 이벤트 기반 또는 비동기 프로그래밍과 잘 맞다.
  • 단점:
    • 제어 흐름이 복잡해진다. Non-blocking 작업이 완료되었는지 확인하고, 필요한 경우 다시 시도하거나 콜백 함수를 사용해야 한다.
    • 타이밍 문제를 처리하는 코드가 더 복잡해지며, 여러 작업을 동시에 처리하는 경우 코드 유지보수가 어려울 수 있다.

 

3. Blocking과 Non-blocking의 비교

특징  Blocking (블로킹)  Non-blocking (논블로킹)
작업 처리 방식 작업이 완료될 때까지 대기 작업을 기다리지 않고 즉시 반환
응답성 작업 완료 시까지 다른 작업을 진행하지 않음 작업이 완료되지 않더라도 다른 작업을 즉시 진행 가능
사용 편리성 구현이 간단하고 이해하기 쉬움 비동기 작업의 복잡성으로 인해 구현이 복잡해질 수 있음
성능 대기 시간이 긴 경우 성능 저하 더 나은 응답성과 성능을 제공
예시 파일 읽기/쓰기, 네트워크 소켓 대기 등 논블로킹 I/O, 비동기 함수 호출, 이벤트 기반 프로그래밍
코드 예시 recv()가 데이터를 받을 때까지 대기 recv()가 데이터를 받을 때까지 대기하지 않음

 

4. Blocking과 Non-blocking 사용 사례

Blocking 사용 사례

  1. 단일 스레드 프로그램: 프로그램이 작업 완료까지 기다려도 상관없는 경우. 예를 들어, 계산을 수행한 후 결과를 출력하는 경우에는 블로킹 방식이 적합할 수 있다.
  2. 입출력 작업: 간단한 파일 입출력, 네트워크 소켓 통신 등에서 블로킹 방식은 적합할 수 있다. 이 방식에서는 작업 순서가 직관적이므로 유지보수가 쉬울 수 있다.
  3. 일반적 사용자 인터페이스(UI) 작업: 입력 이벤트를 처리할 때 순차적으로 입력을 처리하는 방식.

Non-blocking 사용 사례

  1. 네트워크 프로그래밍: 네트워크 응답 시간이 길 경우, Non-blocking 소켓이나 비동기 네트워크 통신을 사용하여 프로그램이 응답을 기다리는 동안 다른 작업을 수행할 수 있다.
  2. 멀티태스킹: 여러 작업을 병렬로 처리해야 하는 경우. 예를 들어, 서버에서 다수의 클라이언트 요청을 처리할 때 Non-blocking 방식이 유리하다.
  3. 비동기 이벤트 처리: 이벤트 기반 프로그래밍(예: JavaScript의 async/await 또는 Python의 asyncio)에서는 Non-blocking 방식이 필수적이다.
  4. 그래픽 처리 및 게임 개발: 빠른 응답과 함께 다양한 이벤트를 처리해야 하므로, Non-blocking 방식이 중요하다.

 

  • Blocking은 작업이 완료될 때까지 해당 프로세스나 스레드가 대기하는 방식으로, 구현이 간단하지만 대기 시간이 길면 성능에 영향을 줄 수 있다. 주로 단순한 I/O 작업이나 단일 스레드 프로그램에서 사용된다.
  • Non-blocking은 작업을 기다리지 않고 즉시 반환하여 다른 작업을 진행할 수 있는 방식으로, 응답성을 높이고 비동기적 작업에 적합하다. 하지만 더 복잡한 제어 흐름을 요구하며, 주로 멀티태스킹, 네트워크 프로그래밍, 비동기 I/O에서 사용된다.

이 두 개념은 시스템의 요구 사항에 따라 적절히 선택해야 하며, 특히 응답성이나 성능이 중요한 경우에는 Non-blocking 방식이 유리할 수 있다. 반면, 구현의 간단함이 중요할 때는 Blocking 방식이 더 적합할 수 있다.

728x90

'Backend study > Backend theory' 카테고리의 다른 글

TCP's 3-way handshake, 4-way handshake  (0) 2024.09.20
TCP 와 UDP  (1) 2024.09.19
경쟁 조건(Race Condition)과 교착 상태(Deadlock)  (0) 2024.09.17
프로세스(process)와 스레드(thread)  (2) 2024.09.16
HTTP와 HTTPS  (1) 2024.09.15