본문 바로가기
개발지식

블로킹과 논블로킹, 동기와 비동기 파이썬예제

by hunovator 2024. 2. 27.
반응형

블로킹(blocking), 논블로킹(non-blocking), 동기(synchronous), 비동기(asynchronous)는 프로그래밍 및 컴퓨터 시스템에서 중요한 개념입니다. 이러한 개념들은 코드의 실행 흐름과 상호작용하는 방식을 설명하며, 다양한 상황에서 프로그램의 동작을 이해하고 설계하는 데 필수적입니다.

블로킹

블로킹은 어떤 작업이 완료될 때까지 다른 작업이나 코드 실행을 멈추는 것을 의미합니다. 이는 특히 I/O 작업(파일 읽기/쓰기, 네트워크 통신 등)에서 많이 발생합니다. 예를 들어, 파일을 읽을 때 파일의 끝까지 읽을 때까지 다음 코드나 작업이 실행되지 않습니다.

with open('file.txt', 'r') as f:
    data = f.read()  # 파일의 끝까지 데이터를 읽을 때까지 블로킹됨
    # 파일을 다 읽은 후에 다음 코드가 실행됨
    process_data(data)

논블로킹

논블로킹은 어떤 작업이 완료될 때까지 기다리지 않고 다른 작업을 계속할 수 있는 것을 의미합니다. 이는 일반적으로 비동기적인 작업에서 발생합니다. 예를 들어, 네트워크 호출을 보낼 때 블로킹 방식이 아닌 경우, 다른 작업을 수행하다가 응답을 기다리지 않고 계속할 수 있습니다.

import requests

# 논블로킹 방식의 HTTP GET 요청
response = requests.get('https://api.example.com/data', timeout=1)
# 응답을 기다리지 않고 다음 코드 실행
process_response(response)

동기

동기는 코드가 순차적으로 실행되는 것을 의미합니다. 즉, 한 작업이 완료될 때까지 다음 작업이 실행되지 않습니다. 함수를 호출하고 그 함수가 반환될 때까지 기다리는 것이 동기적인 방식의 예입니다.

import requests

# 논블로킹 방식의 HTTP GET 요청
response = requests.get('https://api.example.com/data', timeout=1)
# 응답을 기다리지 않고 다음 코드 실행
process_response(response)

비동기

비동기는 코드가 순차적으로 실행되지 않고 작업이 완료되는 대로 계속 진행될 수 있는 것을 의미합니다. 작업이 완료될 때까지 대기하지 않고 다음 코드를 실행할 수 있습니다. 이는 특히 네트워크 호출이나 파일 I/O 등 시간이 오래 걸리는 작업에서 유용합니다.

import asyncio

# 비동기적인 방식의 함수 호출
async def fetch_data():
    # 네트워크 호출을 기다리지 않고 다음 코드를 실행
    response = await async_http_get('https://api.example.com/data')
    process_response(response)

# asyncio를 사용하여 비동기 함수 호출
asyncio.run(fetch_data())


아래는 Python에서 블로킹과 논블로킹, 그리고 동기와 비동기를 함께 사용한 예제 코드입니다.

import requests
import asyncio

# 블로킹 HTTP GET 요청
def blocking_http_get(url):
    response = requests.get(url)
    return response.text

# 논블로킹 HTTP GET 요청
async def non_blocking_http_get(url):
    response = await async_http_get(url)
    return response

# 비동기적인 네트워크 호출
async def async_http_get(url):
    response = await asyncio.sleep(1)  # 가상의 네트워크 호출을 대신함
    return f"Response from {url}"

# 동기적으로 데이터 처리
def process_data_sync(data):
    print("Processing data synchronously:", data)

# 비동기적으로 데이터 처리
async def process_data_async(data):
    print("Processing data asynchronously:", data)

# 동기적인 예제
def synchronous_example():
    data = blocking_http_get('https://api.example.com/data')
    process_data_sync(data)

# 비동기적인 예제
async def asynchronous_example():
    data = await non_blocking_http_get('https://api.example.com/data')
    await process_data_async(data)

# 실행
synchronous_example()  # 블로킹 호출
asyncio.run(asynchronous_example())  # 비동기 호출


이러한 코드를 통해 블로킹과 논블로킹, 동기와 비동기의 차이를 이해하고, 각각의 장단점을 파악할 수 있습니다.

반응형