개념익히기: 비동기 (async)

태훈입니다·2022년 12월 20일
0

개념익히기

목록 보기
3/6

Node.Js 를 공부할 때,
가장 처음 배우는 게 Node.JS의 특징이었는데,

그 특징 2가지는 아래와 같다.

1.Non-blocking I/O
2. Event driven

여기서 2번 Event driven은, 이벤트 기반이라는 뜻으로
이벤트 루프를 통해 실행되는 node.js의 특성인데,
다음 시간에 공부해볼 개념이니 오늘은 넘어가고,
1번인 Non-blocking I/O 에 대한 걸 익혀보자!

내가 애플코딩 강의를 보던 중, 쉬운 예를 보고 이해했는데,
다음의 예를 보자!

영화관 서버가 있다. 서버는 호스트와 클라이언트 사이에서,
클라이언트가 서버에게 요구하는 걸, 호스트쪽에 준비된 것을 가져다 주는 역할을 하는 게 서버인데,

A,B,C,D 각각의 사람이 영화관 표를 1장,1장,100장,1장 예매한다고 생각해보자.

먼저 non-blocking i/o 가 아닌 언어로 서버를 만들게되면,
A에게 주문을 받고, 1장을 예매해서 전달하고,
B에게 똑같이 전달,
C에게는 100장을 ,
D는 그걸 다 기다렸다 1장을 받는다.

한 눈에 보기에도 단점이 명확하다. 장점은 보이지 않지만, 장점 또한 있다.
이러한 과정을 동기 라는 개념 (sync) 라고 보면 되는데,
서버가 요청을 받고 처리를 하는 과정에서, A,B,C,D 각각의 요청에
멈춰서 해결을 하고 진행하는 방식이다. 덕분에 서버에 요청이 몰리게 되면,
D의 상황처럼 오랜 시간을 기다렸다가 1장을 받는 경우가 생기며
비효율적이다.
장점으로는 코드를 짜는 과정이 단순해서 쉽다는 장점이 있다.

이제 Node.js의
Non blocking I/O , 비동기 처리를 통해 이를 처리하게 된다면 어떻게 되는지 알아보자.

먼저 A,B,C,D에게 각각의 영화표 예매 숫자를 요청받고,
처리가 빠른 A,B,D부터 1장의 영화표를 나눠준 뒤, 그 다음 C의 100장을 처리한다.
단순하고 효율적인 처리를 하며, 이 과정을 통해 서버에 무수히 많은 요청이 들어와도,
효율적인 처리를 할 수 있다는 장점이 있다.
어쩌면 동기는 전화통화, 비동기는 E-mail이라고 생각할 수도 있다.
서버(나)와 클라이언트(A)가 어떠한 메세지(요청)을 전달 받는다고 해보자.
동기(전화통화)를 통한다면,

A가 나에게 전화를 해서, 메시지를 전달하고. 나는 그 메시지를 듣고 이해해서 답장을 보내는 건데, 이 때 나는 다른 아무 작업도 할 수 없다.

비동기는 E-mail이다.
A가 나에게 E-mail을 보내면, 나는 E-mail을 받아 메시지를 읽고, 답장을 바로 할지,
나중에 할 지 선택할 수 있다.

아무래도 일상생활에서 동기, 즉 동기화는 많이 들어봤지만
프로그래밍, 특히 내가 공부하는 node.js에서의 동기화는
아직 node.js로 깊이있는 작업을 해보지 않아서, 정확한 비유를 들기가 무척 어렵지만.

일상 생활에서의 동기화, 비동기 작업은 쉽게 알 수 있다.
차에서도 sync 버튼을 쉽게 찾을 수 있는데, 동기화 이다.
운전석과 조수석의 온도에 차이를 두고 싶을 땐 꺼두고,
같은 온도로 동기화하려면 키면 되듯이 쉽게 접할 수 있다.

생활코딩의 예를 가져와봤다.

빨래 설거지 청소 . 3가지 작업이 있다고 생각해보자.

내가 이 작업을 반드시 빨래 > 설거지 > 청소 순으로 마쳐야 한다면?
동기 작업을 통해 순서대로 처리하면 된다.

빨래 30분 > 설거지 20분 > 청소 30분 순으로 작업을 진행하고 ,끝낼 수 있는데 총 소요시간은 80분이고 원하는 순서대로 작업을 할 수 있다.
이게 프로그래밍에서의 동기 개념 비유이다.

단, 순서와 상관없이 조금 더 효율적으로 일을 처리하고싶다면?
(비용 제외)
각 작업들을 각 작업을 해주는 용역업체에 맡겨서 처리하면 된다.
빨래업체 전화>1분 청소업체 전화>1분 설거지>내가 처리
이런식으로 하면 전화통화 2분, 설거지20분, 그리고 각 업체에서 일을 처리하고 업무 종료 전화를 받게 되는 시간까지 포함하면
대략 3가지 작업을 비동기 처리 시, 52분이 걸린다. 30분이 줄어드는 대신,
청소,빨래 업체 중 어디가 먼저 처리할 지는 알 수 없다.

이제 sync,async를 이해하려는 이유와, 노드JS에서의 코드를 실제로 보며
알아보자.

노드 JS에선 fs.fileread라는 메서드가 있다.
노드에서는 비동기처리를 지향하기에, Sync를 따로 붙이지 않으면 비동기,
아래 코드처럼 Sync를 붙이면 동기처리로 작업한다.

메모장 :data.txt = 'Hello Sync, Async' // 코드가 아님 메모장임

const fs = require('fs');
console.log('1')
const data =
fs.readFileSync('data.txt',{encoding:'utf8'})
console.log(data) 
console.log('2')

동기 방식의 위 코드에서 처리 과정을 살펴보면,
1. 1을 출력한다.
2. data에 할당 된 readFileSync를 통해, data.txt를 읽는다.
( 읽는데 소요된 시간 = 30분 )
3. 30분 뒤 Hello Sync, Async 출력
4. 2 출력

이게 동기 처리다. 보이는대로 순서대로 일을 처리하며, 막히는 곳에선(2번)
그걸 처리할 때까지 기다렸다가, 다음 작업을 진행한다.

다음은 비동기처리 코드이다.

메모장 :data.txt = 'Hello Sync, Async' // 코드가 아님 메모장임

const fs = require('fs');
console.log(1)
const data =
fs.readFile('data.txt',{encoding:'utf8'},(err,data)=>{
console.log(data)
console.log(2)});
console.log(3)

이 코드에선 동기 코드와 다르게 , 매개변수로 err,data를 매개변수로 갖는 익명함수를 콜백함수로 받는다.
이 때 실행과정은

1.1을 출력한다.
2.readFile 작업을 시작한다. 단, 비동기기에 따로 백그라운드에서 처리를 해서, 완료가 된다면 출력해준다.
3.3을 출력한다.
4.30분뒤 읽는 게 완료되면, data와 2를 차례대로 출력해준다.

이게 비동기 방식인데, 보다시피 순서와 상관없이 오래걸리는 작업을 비동기로 빼주면, 처리하는 과정에서 백그라운드로 빼놓고, 처리가 될 때까지 다른 작업들을 진행해서 많은 양의 요청들을 처리하거나 업무처리방식을 효율적으로 바꿀 수 있다.
이게 가장 큰 장점으로 작용해서, Node.js로 웹페이지 서버를 만들 때 유용한거라는데.. 얼른 Node.js 공부를 마스터하고싶다!

아직 어려운 개념들을 잘 설명하기엔 부족하지만..
언젠가는 누군가에게 개념을 술술 설명하는 내가 됐으면 좋겠다.

다음에 알아 볼 개념은

=> 콜백함수, Event Driven 이다!

profile
개발 공부를 하고 있는 비전공자입니다!

0개의 댓글