동기/비동기, 블로킹/논블로킹에 대해서 알아보자

Alex·2025년 2월 24일
0

CS를 공부하자

목록 보기
38/74

동기와 비동기는 작업의 실행 방식을 말한다.

동기 방식은 한 작업이 끝나야만 다른 작업이 시작되는 순차적인 처리방식이다. 작업의 완료를 기다리는 동안엔 다른 작업을 수행할 수 없다.

동기 방식은 현재 실행 중인 작업이 완료될 때까지 다음 작업이 대기 상태에 있어야 하기 때문이다.

비동기 방식은 한 작업이 끝나기를 기다리지 않고 다음 작업을 실행할수 있다.

비동기 방식은 특히 I/O 작업이나 네트워크 요청과 같이 대기 시간이 긴 작업을 처리할 때 유용하다.

보통 성능을 향상시키기 위해서 비동기를 많이 사용한다. I/O같은 느린 작업이 발생할 때 기다리지 않고 다른 작업을 동시에 처리하면서 멀티 작업을 진행할 수 있어서다.

작업 3개를 요청했는데, 응답에서 그 순서가 지켜진다면 동기이고 어떤 응답이 먼저 올지 모른다면 비동기라고 볼수 있다.

블로킹과 논블로킹은 뭐야?

블로킹/논블로킹은 사실상 동기/비동기와 개념적으로는 유사한 것으로 보인다.

스택오버플로우에서 좋은 설명이라고 평가받는 내용을 정리해보자.

Asynchronous Asynchronous literally means not synchronous. Email is asynchronous. You send a mail, you don't expect to get a response NOW. But it is not non-blocking. Essentially what it means is an architecture where "components" send messages to each other without expecting a response immediately. HTTP requests are synchronous. Send a request and get a response.

비동기는 말그대로 동기적이지 않은 것이다. 이메일은 비동기다. 이메일을 보내면, 이에 대해 바로 응답을 받을거라고 생각하지 않는다.

그렇다고 이게 논블로킹은 아니다. Http 리퀘스트는 동기적이다. 요청을 보내고 응답을 받는다.

Non-Blocking This term is mostly used with IO. What this means is that when you make a system call, it will return immediately with whatever result it has without putting your thread to sleep (with high probability). For example non-blocking read/write calls return with whatever they can do and expect caller to execute the call again. try_lock for example is non-blocking call. It will lock only if lock can be acquired. Usual semantics for systems calls is blocking. read will wait until it has some data and put calling thread to sleep.

논블로킹은 대부분 I/O 작업에 사용한다. 시스템 콜을 요청하고서, 즉시 반환되며 작업이 완료되지 않은 상태라면 나중에 다시 시도한다.

스레드가 차단되지 않고 계속 다른 작업을 수행한다. (번호표를 받고 다른 일을 하다가 주기적으로 확인하는 것과 같다)

블로킹은 카페에서 주문을 하고 그 자리에서 계속 기다리는 것과 같다. 스레드가 작업 완료가 될때까지 기다린다. try_lock과 같은 non-blocking 호출을 즉시 결과를 반환한다. 일반적인 시스템콜을 블로킹 방식이다.

To me, non-blocking means that the execution of an action in a thread does not depend on the execution of other threads, it does in particular not require critical section.
Asynchronous means that the execution happens outside the flow of the caller, and is potentially deferred. The execution typically occurs in another thread.

이런 내용도 있다. 논블로킹은 스레드의 액션이 다른 스레드에 의존하지 않는 것이고, 비동기는 액션 자체가 콜러의 흐름 밖에서 이뤄지고 지연될 가능성이 있다. 액션은 다른 스레드에서 발생한다.

이벤트의 개념은, 무언가가 발생했을 때(occur) 알림을 받는 개념이다. 쓰기가 비동기적으로 처리됐을 때, 쓰기가 완료됐을 시 다른 시스템에게 알림을 전달해줄 수 있다.


블로킹 방식

# 카페 주문 예시
def orderCoffee():
    # 커피가 완성될 때까지 이 함수에 갇혀있음
    # 다음 줄의 코드를 실행할 수 없음
    waitUntilCoffeeIsDone()  # 여기서 멈춤
    return coffee

# 메인 프로그램
coffee = orderCoffee()  # 여기서 대기
doNextTask()           # 커피가 나올 때까지 실행 안 됨




논블로킹
# 카페 주문 예시
def orderCoffee():
    # 주문만 하고 바로 리턴 -->다른 작업 가능
    orderNumber = placeOrder()
    return orderNumber

# 메인 프로그램
orderNum = orderCoffee()  # 바로 리턴됨
doNextTask()             # 바로 실행 가능
checkOrderStatus()       # 나중에 상태 확인

논블로킹 방식은 특히 이벤트 기반 프로그래밍이나 콜백 함수를 사용하는 비동기 프로그래밍에서 자주 사용된다. 왜냐하면 이 방식을 통해 I/O 작업의 대기 시간 동안에도 다른 작업을 수행할 수 있어 전체적인 프로그램의 효율성을 높일 수 있기 때문이다.

1000바이트의 데이터를 받는 포트를 생각해보자.
블로킹 read 아키텍처에서는, 1000바이트를 모두 받을 때까지 기다리거나 작업을 포기해야 한다.

비동기 구조에서는 1000바이트를 원한다고 요청하고, 1000바이트가 도착하면 알림(notified)을 받는다. (알림구조가 돼있다면)

논블로킹 아키텍처에서는, 아무때나 얼마나 많은 바이트가 도착했는지를 물어본다. 데이터가 다 도착했는지 확실하게 아는 방법은 직접 물어보는 방법뿐이다.

참고자료

동기와 비동기, 블로킹과 논블로킹의 차이점

What's the difference between: Asynchronous, Non-Blocking, Event-Base architectures?

profile
답을 찾기 위해서 노력하는 사람

0개의 댓글