iamabear09 / __STUDY__core

개발자로서 필요한 이론적인 학습 내용에 대해서 기록
0 stars 0 forks source link

Synchronous vs Asynchronous / Blocking vs Non-Blocking #1

Open iamabear09 opened 7 months ago

iamabear09 commented 7 months ago

Synchronous

어원

두 개 이상의 작업

Synchronous 의미



Asynchronous

Asynchronous의미

작업 결과 처리X - Write 작업 작업 결과 처리O - Message queue에 작업 결과가 등록되는 경우



Synchronous & Asynchronous & Blocking & Non-Blocking 조합

image



💻참고자료

https://deveric.tistory.com/99

iamabear09 commented 6 months ago

동기 & 비동기에 대한 생각 정리


Synchronouse

두 개 이상의 주체가 서로 동시에 수행하거나, 동시에 끝나거나, 끝나는 동시에 시작하는 것 즉 두 작업의 시작 종료 시간이 관련되어있다.

🙋‍♂️ 왜 동기적인 로직이 나오게 되었을까...? A가 작업을 진행하기 위해서 B의 작업 결과 필요한 경우, 동기 로직 구현이 가장 기본적인 생각이다.

동기 로직이 좋아서 동기 로직을 사용하는 것이 아니다. 과거에도 작업의 결과가 필요하지 않거나 확인할 필요가 없다면 비동기 적으로 구현했다.


🙋‍♂️ 만약 오래 걸리는 작업이 진행되는 동안 다른 작업을 한다면...? Synchronouse하다고 가정하면, B의 작업이 끝나는 순간 A는 다음 작업을 진행할 것이다.

만약 기다리는 동안 다른 작업을 하게 된다면, 해당 작업은 B의 작업이 끝나는 즉시 현재 작업을 멈추고 원래 작업을 진행해야 한다. 하지만, 그런 작업을 그렇게 중단할 거면 그냥 다른 Thread에서 온전하게 실행되도록 하는 것이 맞다.

B의 작업이 끝나는 순간 을 알기 위해서

  1. CPU를 차지하고 계속 Polling 할 수 있다. (비 효율적이다.)
  2. CPU를 양보하고 Blocking 되어서 Interrupt를 기다릴 수 있다.

따라서 Synchronouse & Blocking 이 일반적인 조합이다.


🙋‍♂️진행 중인 작업을 다 완료하고 B의 결과를 확인해서 기존 작업을 수행한다면...? 이것이 바로 Asynchronouse 이다. 따라서, 왜 Asynchronouse & Non-Blocking 조합이 자연스러운지 알 수 있다.


Asynchronouse

두 주체가 서로의 시작, 종료 시간과는 관계 없이 별도의 수행 시작/종료 시간을 가지고 있는 경우이다.

Asynchronouse 하다고 해서 A가 B의 작업의 결과를 신경 쓰지 않는다는 말은 아니다.


하지만, A가 B의 작업 결과를 신경쓰지 않는다면 반드시 Asynchronouse 하다. A가 B의 작업 결과를 신경쓰지 않는다면


🙋‍♂️만약 기다리는 동안 할 작업이 없다면...? 이것이 Non-blocking Sync 이다.


🙋‍♂️만약 중간에 할 일을 금방 하고 B의 작업만 기다린다면...? 이건 결과를 요청하는 시점에서 Blocking 되긴 한다.. 이것을 Async Blocking 이라고 해야 하나? 만약 B가 작업을 시작하는 시점부터 종료 시점까지 Blocking 되면 Async Blocking이 확실한데... 애매한 것 같다.

iamabear09 commented 6 months ago

글을 적고 보니 이상한 지점 발견

다시 생각해야 하는 지점

Asynchronouse 하다고 해서 A가 B의 작업의 결과를 신경 쓰지 않는다는 말은 아니다.

  • 계속 Polling 만하면서 B의 작업이 완료되기 까지 기다린다면 → Non-Blocking Sync
  • 다른 일을 하면서 중간 중간 B가 작업이 완료되었는지 한번씩 Polling 한다면 → Async

🙋‍♂️만약 중간에 할 일을 금방 하고 B의 작업만 기다린다면...? 이건 결과를 요청하는 시점에서 Blocking 되긴 한다.. 이것을 Async Blocking 이라고 해야 하나? 만약 B가 작업을 시작하는 시점부터 종료 시점까지 Blocking 되면 Async Blocking이 확실한데... 애매한 것 같다.


작업의 결과가 필요한 Async에서 Polling 을 통해 다른 작업 확인하면서 진행 시



🙋‍♂️Async란 결과를 신경 쓰지 않는것 이라고 정의해야 하나...?

이렇게 정의하면 Sync는 결과를 신경 쓰는 것이고, 따라서 Non-Blocking Sync 로직에는

작업의 결과를 신경쓰지 않는다면, 두 작업의 시작 및 종료 시점은 상관이 없어진다.


🙋‍♂️기존 Sync에서 Async로의 변화...? 기존 Sync로직을 작성한 이유는 작업의 결과가 있어야 다음 동작을 수행할 수 있기 때문이였는데 콜백 함수 즉, 작업의 결과로 어떤 동작을 수행해야 하는지 까지 같이 전달하면서 작업의 결과를 기다릴 필요가 없어졌다.



질문

Async란 작업의 결과를 신경 쓰지 않는 것 일까? 아니면, 두 작업의 시작 종료 시점이 상관 없는 것일까?

iamabear09 commented 6 months ago

비동기 로직의 종류를 모아보자.

Kafka 에서 Producer가 Message를 전송하는 경우


🙋‍♂️ 다른 Thread에서 작업을 시키면 Async 일까?

iamabear09 commented 6 months ago

Synchronouse programming

image



Asynchronouse Programming

📌Asynchronouse Programming V1


📌Asynchronouse Programming V2

image


📌Asynchronouse Programming V3

image


📌Asynchronouse Programming V4

image


Asynchronouse Programming != Multi-threading

Asynchronouse Programming

Multi-threading


Asynchronouse Programming 을 가능하게 하는 것

Multi-Threads Multi-Threads만 있다고 하더라도 비동기 프로그래밍이 가능하다. Asynchronouse Programming V1 & V2 에서 예시를 살펴봤다.


Non-block I/O Non-block I/O만 있다고 하더라도 비동기 프로그래밍이 가능하다. Asynchronouse Programming V3 에서 예시를 살펴봤다.


Multi-Threads & Non-block I/O 하지만 Multi-ThreadsNon-block I/O 모두 적절하게 섞는 것이 가장 효율적인 방법이 된다. Asynchronouse Programming V4 에서 예시를 살펴봤다.



I/O 관점에서 Synchronouse & Asynchronouse


case 1

Synchronouse I/O

Asynchronouse I/O


case2

Synchronouse I/O

I/O Multiplexing은 요청자가 결과를 직접 챙겨야 한다. 또한, image


case3

Asynchronouse I/O

image



백엔드 아키텍처 관점에서 Synchronouse & Asynchronouse

Synchronouse Communication

image


Asynchronouse Communication

Message Queue가 도입됨으로서 API call의 결과를 기다리지 않아도 된다.

🙋‍♂️ 만약 B의 API call 호출의 결과가 필요하다면...?

  1. Synchronouse Communication을 사용한다.
  2. 이때도 Message Queue를 도입한다. 하지만, 이 경우 결과의 신속한 처리가 늦어질 수 있다.

image




참고자료

https://www.youtube.com/watch?v=EJNBLD3X2yg

iamabear09 commented 6 months ago

I/O 종류



Block I/O

image

network socket 에서 block I/O 란..?

image




non-blcok I/O

block I/O와 다르게 요청에 대한 현재 상태를 즉시 리턴 한다.

image

  1. read non-blocking system call
  2. kernel 에서 데이터가 준비되지 않았으므로 -1 return
  3. 바로 return 되었으므로 Thread는 다른 동작 수행 가능
  4. kernel은 데이터를 준비 해 놓는다.
  5. 시간이 지나고 다시 read non-blocking system call
  6. 데이터 read 완료


network socket 에서 non-block I/O 란..?


non-block I/O에서 I/O 작업의 완료를 어떻게 확인할 것인가...?


1. 작업 완료를 계속 확인

image



2. I/O multiplexing

관심있는 I/O 작업들을 동시에 모니터링 하고 그 중 완료된 I/O 작업을 한번에 알려준다.

image

여러 socket에 대해서 read system call 호출 시 Thread Blocked or Thread Run 모두 가능하다.

  1. kernel은 데이터가 준비되면 thread를 깨워서 알려준다.
  2. 깨어난 Thread 데이터를 차례로 읽어와서 처리하면 된다.


I/O multiplexing 종류


epoll 동작

  1. socket에 read 이벤트가 발생하면 알려 달라고 epoll에 등록한다.
  2. 클라이언트가 요청 전송 (특정 socket에 read 이벤트 발생)
  3. epoll은 Thread를 깨워주고 어느 소켓에 데이터가 있는지 알려준다.
  4. Thread는 해당 정보를 바탕으로 해당 소켓들만 처리를 해주면 된다.
    • 이때 Thread Pool이 있다면 이러한 요청을 Thread에 할당하면 된다.

image



3. Callback / Signal 사용

  1. aio_read non-blocking system call
  2. Therad는 자신의 할 일을 한다.
  3. 데이터가 완료되면 callback을 통해 처리된다.

image



I/O 구분의 논란...

I/O multiplexing 이 왜 Non-blocking 인가?? 이건 오히려 Sync & Non-blocking 에 가깝다, 이유1. I/O multiplexing 시 결과를 직접 요청자가 직접 챙긴다. 이유2. I/O multiplexing 시 구현에 따라서 Non-blocking 모드가 될 수 있다.

image



참고 자료

https://www.youtube.com/watch?v=mb-QHxVfmcs

iamabear09 commented 6 months ago

Sync, Async, Blocking, Non-blocking

Sync, Async 판단 기준은 "내가 결과를 가만히 기다리고 있는가" 를 생각해보면 된다.

1. I/O multiplexing

➡️ Async & Blocking



2. Async DB 통신

상황

구현

➡️ Async & Blocking