우리는 프로그램을 클릭 하거나 어떤 명령어로 실행한다.
이러한 프로그램을 실행하기 위해서는 대표적으로 프로세스와 스레드가 존재하는데, 오늘 이 부분에 대해서 학습하였다.
1. Process, Thread
프로세스와 스레드는 어려운 개념이라고 생각한다.
다만 프로그래밍을 하기 위해서라면 최소한 개념 정도는 짚고 넘어가는 것이 좋다고 생각한다.
프로세스와 스레드에 관해서 간단하게 정리해보자면,
- Program : 실행 프로그램이라고 부르듯, 실행할 수 있는 파일 → 코드로 짜놓은 파일
- Process : 프로그램을 실제로 실행하기 위해 OS에서 할당하는 작업의 단위
- Thread : 프로세스안에 존재하며 프로세스를 돕기 위한 작업의 단위

위 그림을 보면 프로세스안에 스레드가 여러 개 있는 것을 확인할 수 있다.
주위에서 싱글스레드니 멀티스레드니 하는 용어를 들어본 적이 있을 텐데, 위 그림은 하나의 프로세스안에 여러 개의 스레드가 존재하고 있어서 멀티스레드라고 할 수 있다.
더 자세하고 깊이 있는 내용을 원한다면 아래 글을 참고하면 된다.
👩💻 완전히 정복하는 프로세스 vs 스레드 개념
한눈에 이해하는 프로세스 & 스레드 개념 전공 지식 없이 컴퓨터의 프로그램을 이용하는데는 문제 없어 왔지만 소프트웨어를 개발하는 사람으로서 컴퓨터 실행 내부 요소를 따져보게 될때, 아
inpa.tistory.com
2. Node.js의 특징
Node.js의 특징은 크게 4가지가 있다.
- Javascript 언어로 백엔드를 구축할 수 있음
- Single Thread
- Non-blocking (I/O)
- Event Loop
1) Javascript
Javascript언어는 기존에 프론트 영역(브라우저)에만 적용할 수 있었으나, Node.js를 사용하면서 백엔드(서버)도 구축할 수 있게 되었다.
2) Single Thread
위에서 살펴보았던 Thread가 하나의 프로세스 안에 하나만 존재하는 것이다.
그렇기 때문에 한 번에 하나의 작업만 가능하다.
그 말인 즉슨, Call Stack이 하나라는 말과 같다.
정리하자면 여러 가지의 작업인 A, B, C, D가 있고 A - B - C - D 순서로 작업을 진행한다고 했을 때,
A가 끝나면 B를, B가 끝나면 C를, C가 끝나면 D를 실행하는 것과 같다.
다른 예로 A(B(C(D))) (= A안에 B안에 C안에 D) 순서로 작업을 진행한다고 했을 때는 D - C - B - A 순으로 작업이 진행된다.
또한, 오류(에러)를 만나면 프로그램이 중단되어 버리는 특징이 있다.
3) Non-blocking (I/O)
I/O, Input/Output인 파일 입출력에 적용되는 특징이다.
간단하게 말하자면 A.txt와 B.txt가 있고, A를 먼저 읽은 후 B를 읽는 코드가 있다고 가정해보자.
A를 먼저 다 읽은 다음 B를 읽는 것이 순서대로 진행하는 방법이다.
하지만 Node.js는 동시에 처리 가능한 작업은 백그라운드로 넘겨서 최대한 빠르게 작업을 할 수 있는 특징이 있다.
4) Event Loop
굉장히 복잡한 개념이라고 할 수 있다.
코드가 실행되면 콜 스택에 작업을 차례대로 쌓게 된다.
만약 이벤트가 들어오면 이벤트 리스너에 이벤트를 등록한다.
이 이벤트를 백그라운드에 담고 있다가 이벤트가 실행될 타이밍이 되면 태스크(콜백) 큐에 있던 이벤트를 콜 스택에 옮긴다.
이벤트 루프는 콜 스택과 콜백 큐를 계속해서 감시하면서 콜 스택이 비워지는 경우, 콜백 큐에 있던 콜백을 콜 스택으로 옮겨서 콜백을 실행하게 된다.
아래 글에 자세한 설명과 그림이 있어서 참고하면 좋을 듯 하다.
[도대체 이벤트 루프가 뭔가요?] (https://baeharam.netlify.app/posts/javascript/event-loop)
[JS] 도대체 이벤트 루프가 뭔가요? - 배하람의 블로그
What the heck is the event loop anyway? 영상을 보고 정리한 글이다. 강연자가 JS를 정의할 때 다음과 같이 설명한다. ” 자바스크립트는 싱글 쓰레드 기반이며 논 블로킹 방식의 비동기적인 동시성 언어
baeharam.netlify.app
3. Module 다루기
Javascript도 모듈화가 가능하다.
모듈을 만들고 가져오는 방법에 대해서 알아보도록 하자.
먼저 모듈을 만드는 과정이다.
// [math.js]
// math module
// add(): 더하기 함수를 정의한 파일
const add = (a, b) => a + b;
// add()함수를 다른 js 파일에서 쓸 수 있도록 내보낸다.
module.exports = add;
math.js라는 파일을 생성하고, module.exports를 사용해서 다른 js 파일에서 사용할 수 있도록 설정한다.
다음은 모듈을 불러오는 과정이다.
// [app.js]
// 하나일 때는 변수 이름 바꾸는 것도 가능
const add2 = require('./math');
console.log(add2(1, 1)); // 2
const hello = require('./math');
console.log(hello(2, 2)); // 4
app.js라는 파일을 생성해서 위에서 생성했던 math.js를 불러오는 과정이다.
위에서는 require()를 사용해서 모듈을 가지고 왔는데, 다른 방법도 존재한다.
ES6에서 추가된 방법으로 import / export키워드를 사용해서 모듈을 가지고 오는 방법이다.
이 방법을 사용하기 위해서는 package.json에 "type": "module"을 추가해줘야 한다.
4. 구조 분해 할당
구조를 분해해서 할당한다는 의미이다.
아래 코드를 보면 정말 말 그대로 '구조 분해 할당'이라는 것을 알게 된다.
// 구조 분해 할당: 구조를 분해해서 할당
// 1. 객체({})
const cookie = {
choco: '초코맛 쿠키',
vanilla: '바닐라맛 쿠키',
orange: '오렌지맛 쿠키',
};
console.log(cookie.choco);
console.log(cookie.vanilla);
console.log(cookie.orange);
console.log('-------------------');
// 객체 구조 분해 할당
// key값만 일치하면 알아서 할당해준다.
// 없는 key에 대한 값은 undefined로 출력됨
const { choco, chocochoco, vanilla, orange } = cookie;
/*
const { choco, vanilla, orange } = {
choco: '초코맛 쿠키',
vanilla: '바닐라맛 쿠키',
orange: '오렌지맛 쿠키',
};
*/
console.log(choco);
console.log(chocochoco); // undefined
console.log(vanilla);
console.log(orange);
console.log('-------------------');
[Reference]
1) [프로세스와 스레드 설명] (https://inpa.tistory.com/entry/%F0%9F%91%A9%E2%80%8D%F0%9F%92%BB-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%E2%9A%94%EF%B8%8F-%EC%93%B0%EB%A0%88%EB%93%9C-%EC%B0%A8%EC%9D%B4)
2) [도대체 이벤트 루프가 뭔가요?] (https://baeharam.netlify.app/posts/javascript/event-loop)
[Image]
1) [프로세스와 스레드 이미지] (https://upload.wikimedia.org/wikipedia/commons/thumb/a/a5/Multithreaded_process.svg/1200px-Multithreaded_process.svg.png)