비동기에서 각 맥락에 따른 의미를 설명

GoldenDusk·2023년 8월 30일
0

CS지식

목록 보기
9/26
post-thumbnail

1. 프로그래밍의 관점에서 비동기

🔗 https://velog.io/@pexe99/JavaScript-커피와-함께하는-동기와-비동기
🔗 https://www.youtube.com/watch?v=EJNBLD3X2yg&t=76s
🔗 https://www.youtube.com/watch?v=EJNBLD3X2yg&list=PLcXyemr8ZeoT-_8yBc_p_lVwRRqUaN8ET&index=21

이 글은 쉬운코드님 유투브 강의 듣기 + 따로 공부해서 정리한 글입니다.

🍌 동기[sysncronous | 동시에 일어나는]

  1. 순차적으로 실행

  1. 코드 한줄, 한줄 실행이 끝난 뒤 다음 코드로 넘어가는 처리 방식
  2. 동시에 일어난다는 뜻을 가진다.
  3. 어떤 것을 요청하면 이에 대한 결과가 동시에 일어난다는 뜻입
  4. 요청을 한다면 얼마나 시간이 걸려도 그 자리에서 결과가 주어져야 한다.
  5. 즉, 여러 작업(task)들을 순차적으로 실행하도록 개발

🍌 비동기[asyncronous | 동시에 일어나지 않음]

  1. 동시에 일어나지 않음을 의미
  2. 어떤 것에 대한 요청에 의한 결과가 동시에 일어나지 않음을 의미
  3. 요청해도 이를 즉시 처리하지 않아 결과가 이후에 나오게 된다.
  4. 즉, 여러 개의 요청을 동시에, 독립적으로 처리할 수 있다는 의미입니다.
  5. 실행이 오래걸리는 코드라면, 효율성 측면에서 비동기로 실행하는 것이 더 좋다.
  6. 코드 실행 후, 완료 여부와 관계없이 다음 코드로 넘어가는 처리 방식[다른 작업을 동시에 수행]
  • setTimeOut
  • fetch()

🍌 예시를 들어보자

네 가지 음식 준비하는 방법이 있다. 김치썰기, 스팸 굽기, 국 끓이기, 햇반 데우기…

먼저, synchronous하게 음식을 준비해 볼까?

  1. 차근 차근 준비하는 것을 말함
  2. 너무 오래 걸림

두 번째로, asynchronous하게 음식 준비해볼까? ver1

  1. 두 명이서 음식 준비하기 각자 역할 분담
  2. 시간 단축

그럼 더 빠르게 asynchronous하게 음식 준비해볼까? ver2

  1. 사람을 더 데리고 오기
  2. 사람 4명을 데리고 옴

하지만, 사람이 너무 많이 필요해… 혼자 할 햇반은 전자레인지가 데우는 거니까 나는 다른 걸 같이 할 수 있지 않을까? asynchronous하게 음식 준비해볼까? ver3

저 위에가 최선일까? 아니? 친구 한명만 더 데려오자 asynchronous하게 음식 준비해볼까? ver4

  • 각 사람이 thread를 의미
  • 햇반을 데울 때 쓰는 전자레인지나, 국 끓일 때 쓰는 가스레인지를 I/O
  • 즉 아래와 같은 방식을 non-block I/O라고 할 수 있다.

🍌 그렇다면.. 비동기가 좋기만 할까?

동기 방식

  • 매우 직관적. 어떤 작업을 실행하면 끝날때까지, 그리고 순차적으로 진행하기 때문
  • 하지만, 결과가 주어질 때까지 아무것도 못하고 대기해야 한다.

비동기 방식

  • 결과가 주어지기 전까지 다른 작업을 할 수 있기 때문에 효율적
  • 하지만 동기 방식에 비해 직관적이지 못하고 복잡하다는 단점

그렇다면… 비동기 동작 예시를 봐보자
setTimeout(callback, ms)

//1
console.log('1등!');
//2
setTimeout(function(){
	console.log('2등!')
}. 2000);
//3
setTimeout(function(){
	console.log('3등');
})

2. 비동기 프로그래밍 ≠ 멀티스레딩

🍌 asynchronous programming

  • 여러 작업을 동시에 하는 프로그래밍 방법론

🍌 multithreading

  • asynchronous programming의 한 종류

🍌 asynchronous programming을 가능하게 하는 것은

  1. multi-threads
  • 장점 : 멀티코어 활용 가능
  • 단점 : 스레드를 많이 만들게 되면.. 컨텍스트 스위칭 시 비용이 많아질 수 있음
  • 레이스 컨디션 발생 가능
    • 두 개이상의 프로세스가 공통 자원을 병행적으로 읽거나 쓸 때, 공용 데이터에 대한 접근이 어떤 순서에 따라 이루어졌는지에 따라 그 실행 결과가 달라지는 것

  1. non-block I/O
  • 장점 : 싱글스레드여도 여러 가지 일을 하게 해줌

  1. 두 가지를 잘 버무리면, 적은 스레드로도 좋은 성능을 낼 수 있다.

🍌 자바스크립트는 싱글스레드

💡 파란색과 녹색은 스레드들이 속한 메모리 영역

싱글 스레드

  1. 싱글 스레드를 가지는 프로세스
  2. 스레드가 나오기 전에 프로세스만의 메모리 구조
  3. 한 번에 하나의 작업만 수행 할 수 있다.(이전 작업이 완료되어야지만 다음 작업을 수행)

왜 자바스크립트는 싱글 스레드일까?

  • JavaScript는 call stack이 하나이기 때문에 싱글 스레드인 것

백엔드 프로그래밍의 추세는 스레드를 적게 쓰면서도 non-block I/O를 통해 전체 처리량을 늘리는 방향으로 발전

3. I/O 관점에서 비동기

🍌 non-blocking, blocking이 뭘까?

🔗 https://adrianmejia.com/asynchronous-vs-synchronous-handling-concurrency-in-javascript/
🔗 https://adrianmejia.com/asynchronous-vs-synchronous-handling-concurrency-in-javascript/

동기모델

  • 직렬적[↔ 비동기 : 병렬적]
  • Blocking을 확인 가능
  • 앞에서 스팸 굽기가 끝날 때까지 아무것도 하지 못하는 상황
  • 즉, 동기적인 작업에 따라 이후 작업이 막히게 된 것
  • 반대로 작업이 막히지 않으면 Non-Blocking

그렇다면.. 동기는 Blocking이고 비동기는 Non-Blocking일까? 비슷하면서도 다른 개념이다.

[Boost application performance using asynchronous I/O]

쉬운 코드님의 생각으로 I/O multiplexing(select/poll)의 경우, noti를 받는 것이 아니라 요청자가 결과나 완료를 챙겨야 하기에 Asynchronous이 더 맞는 것 같으며 어떻게 사용하지는에 따라 blocking이 될 수 도 non-blocking이 될 수도 있다. 또한 read/write의 non-blocking으로 돼서 Non-blocking이 좀 더 맞는 것 같다고 하심

🔗 https://developer.ibm.com/articles/l-async/

제어에서의 차이

[Blocking ]

  • 직접 제어할 수 없는 대상의 작업이 끝날 때까지 제어권을 넘겨주지 않는 것입니다.
  • 사전적인 정의로는 막혀버린, 제한된, 대기하는 상태를 의미합니다.
  • 호출된 함수가 자신이 할 일을 모두 마칠 때까지 제어권을 계속 가지고서 호출한 함수에게 바로 돌려주지 않는 경우에 해당합니다.

[ Non-Blocking ]

  • 직접 제어할 수 없는 대상의 작업 처리 여부와 상관이 없습니다.
  • Blocking과는 반대되는 개념입니다.
  • 호출된 함수가 자신이 할 일을 마치지 않았더라도 바로 제어권을 건내주는 경우에 해당합니다.

asynchronous I/O

  • 정의하자면, 요청자가 따로 챙길 필요 없이 os로부터 noti를 받거나 작업을 시작할 때 callback으로 os에서 알아서 callback 실행하는 경우

문맥에 따라서.. CASE 1

  • synchronous I/O = block I/O
  • asynchronous I/O = non-block I/O

문맥에 따라서.. CASE 2

  • synchronous I/O : 요청자가 I/O 완료까지[결과까지] 챙겨야 할 때
  • asynchronous I/O : 완료를 noti 주거나 callback으로 처리

문맥에 따라서.. CASE 3

  • asynchronous I/O : block I/O를 다른 thread에서 실행
  • block 받는 게 싫어서 스레드에 block I/O 처리 후 최종 결과를 합쳐서 처리

4. 백엔드 아키텍처 관점

하나의 서비스는 기능과 역할에 따라 여러 개의 마이크로 서비스로 구성되고 이들 사이에는 빈번하게 커뮤니케이션이 발생 ⇒ 커뮤니케이션 방법에 따라 부르는 것이 달라짐

🍌 Synchronous communication

  • 하나의 응답이 올 때까지 대기했다가 처리 처리
  • API를 전달해서 커뮤니케이션
  • C가 응답 불능에 빠지면 B, A 또한 영향을 받아 비정상적인 상태로 가서 전체 응답 불능 상태로 전체 서비스 장애까지 올 수 있음

🍌 Asynchronous communication

  • Synchronous communication의 문제를 해결하기 위함
  • Message Q라는 버퍼를 이용 ⇒ 처리가 느림(한쪽으로 전달만 해야 하는 상황에서 사용)
  • C가 장애에 빠져도 영향을 받지 않음, 일부 서비스는 문제가 생기나 전체 서비스 장애까지 가지는 않게 됨

그렇다면… 모든 걸 Message Q로? 언제 API를 써야 할까?

  • A에서 B에서 제공하는 데이터를 필요로 하다면 그것은 API로 구현해야 함
    • 영향을 최대한 받지 않게 구현

profile
내 지식을 기록하여, 다른 사람들과 공유하여 함께 발전하는 사람이 되고 싶다. gitbook에도 정리중 ~

0개의 댓글