프로세스 (Process)

정의

운영체제에서 실행 중인 프로그램 인스턴스를 의미. 각 프로세스는 독립된 메모리 공간과 자원을 할당받아 실행된다. 각각의 프로세스는 독립된 실행 흐름을 가지며, 다른 프로세스와는 메모리등의 자원을 공유하지 않는다.

 

자원 할당

각 프로세스는 독립된 메모리 공간을 할당받아 실행되며, 프로세스 간에 메모리나 파일과 같은 자원을 공유하기 위해 별도의 메커니즘이 필요하다. 프로세스는 운영체제로부터 자원을 할당받는 독립적인 개체로 존재한다.

 

동시성과 병렬성(Process) 

각 프로세스는 독립된 실행 흐름을 가지며, 여러 프로세스는 동시에 실행될 수있다. 여러 프로세스가 동시에 실행되는 것을 병렬 실행이라고 한다.

 

스레드 (Thread)

정의

프로세스 내에서 실행되는 작은 실행 단위. 스레드는 프로세스의 자원을 공유하며 실행된다. 한 프로세스 내에서 여러 개의 스레드가 동시에 실행될 수 있다.

 

자원 할당

스레드는 프로세스 내의 자원을 공유하면서 실행되므로, 스레드는 프로세스의 메모리, 파일, I/O등의 자원에 접근할 수 있다. 따라서 스레드 간의 통신과 자원 공유는 상대적으로 간단하게 이루어진다.

 

동시성(Thread)과 병렬성

스레드는 하나의 프로세스 내에서 동시에 실행될 수 있다. 다중 스레드를 사용하면 여러 스레드가 동시에 작업을 처리할 수 있다. 하지만 실제로 동시에 실행되는 것은 여러 스레드의 작업이 CPU의 코어를 번갈아가면서 실행되는 것이고, 스레드는 동시성을 구현하는 데 사용되며, 여러 스레드 간에 작업을 조율하고 자원을 공유하기 위해 동기화 메커니즘을 사용한다.

 

 

 

'Dev > JavaScript' 카테고리의 다른 글

동기 (Synchronous)와 비동기 (Asynchronous)  (0) 2023.05.31
콜백 함수 (Callback Function)  (0) 2023.05.30
이벤트 루프 (Event Loop)  (0) 2023.05.30
데이터 타입의 종류와 메모리 할당  (0) 2023.02.22
JavaScript 설명  (0) 2023.02.13

동기 실행 (Synchronous)

 동기 실행은 코드가 순차적으로 실행되는 방식이다. 한 작업이 끝나기를 기다렸다가 다음 작업을 실행하는 방식. 코드의 실행은 호출된 순서대로 진행되며, 하나의 작업이 완료되기 전까지는 다음 작업이 시작되지 않는다. 동기 실행은 직관적이고 순서가 중요한 작업에 적합하다. 하지만 한 작업이 끝날 때까지 다른 작업을 기다려야 하므로 시간이 오래 걸리는 작업이 있다면 전체 프로그램의 실행이 느려질 수 있다는 단점이 있다.

console.log("첫 번째 작업");
console.log("두 번째 작업");
console.log("세 번째 작업");

위 코드 실행 시 "첫 번째 작업" 부터 차례대로 로그를 출력한다.

 

 

비동기 실행  (Asynchronous)

비동기 실행은 코드의 실행이 순차적이지 않고, 작업이 완료되기를 기다리지 않고 다음 작업을 실행하는 방식이다. 비동기 작업은 별도의 실행 흐름을 생성하여 작업을 백그라운드에서 수행하고, 해당 작업이 완료될 때 결과를 반환하거나 알림을 받는다. 이를 통해 다른 작업을 동시에 수행할 수 있으므로 전체적인 실행 시간을 단축시킬 수 있다. 비동기 실행은 I/O 작업이나 네트워크 요청과 같이 시간이 오래 걸리는 작업에 유용하다.

console.log("첫 번째 작업");

setTimeout(function() {
  console.log("두 번째 작업");
}, 2000);

console.log("세 번째 작업");

위 코드 실행 시 "첫 번째 작업"을 출력한 후, setTimeout 함수는 2초 후에 콜백 함수를 실행한다. 그러나 콜백 함수의 실행을 기다리지 않고, 바로 다음코드 라인으로 넘거간다. 따라서 "세 번째 작업"을 출력 후 2초가 지난 뒤에 "두 번째 작업"을 출력한다.

 

 

파일 읽기 작업 수행 동기와 비동기 차이점

1. 동기적으로 파일을 읽는 작업을 수행한다면, 파일을 읽을 때까지 다음 코드 라인으로 진행되지 않는다.

2. 비동기적으로 파일을 읽는 작업을 수행한다면, 파일 읽기 작업이 백그라운드에서 수행되는 동안 다음 코드 라인을 실행할 수 있다. 파일 읽기 작업이 완료되면 콜백 함수나 promise를 통해 결과를 처리할 수 있다.

'Dev > JavaScript' 카테고리의 다른 글

프로세스 (Process)와 스레드 (Thread)의 차이  (0) 2023.05.31
콜백 함수 (Callback Function)  (0) 2023.05.30
이벤트 루프 (Event Loop)  (0) 2023.05.30
데이터 타입의 종류와 메모리 할당  (0) 2023.02.22
JavaScript 설명  (0) 2023.02.13

콜백함수란?

다른 함수에게 인자로 전달되어 나중에 호출되는 함수

콜백 함수는 비동기적 작업, 이벤트 처리, 데이터 요청 및 처리 등 다양한 상황에서 사용된다.

코드의 유연성과 효율성을 높일 수 있다.

 

콜백 함수의 패턴

비동기 작업의 콜백 함수

  • 다른 함수에게 콜백 함수를 인자로 전달한다. 이때 함수는 비동기적인 작업을 수행으로 콜백 함수를 호출할 수 있다.
  • 작업이 완료되거나 이벤트가 발생했을 때 적절한 동작을 수행할 수 있다.
function asyncOperation(callback) {
  setTimeout(function() {
    console.log('비동기 작업 완료');
    callback();
  }, 2000);
}

function handleCallback() {
  console.log('콜백 함수 호출됨');
}

asyncOperation(handleCallback);
// 2초 후에 '비동기 작업 완료' 출력 후 '콜백 함수 호출됨' 출력

 

이벤트 핸들러의 콜백 함수

  • 이벤트가 발생했을 때 실행될 함수로 콜백 함수를 등록한다.
  • 이벤트가 발생하면 등록된 콜백 함수가 호출되어 특정 동작을 수행한다.
document.getElementById('myButton').addEventListener('click', function() {
  console.log('버튼이 클릭되었습니다.');
});

id가 'myButton'인 버튼을 클릭했을 때 콜백 함수가 실행되며, '버튼이 클릭되었습니다.'를 출력

 

 

배열의 forEach 메소드에 콜백 함수 전달

const numbers = [1, 2, 3, 4, 5];

numbers.forEach(function(number) {
  console.log(number * 2);
});
// 배열의 각 요소에 대해 콜백 함수 실행 후, 2, 4, 6, 8, 10 출력

배열의 각 요소에 대해 콜백 함수를 실행하고, 각 요소에 2를 곱한 결과를 출력

이벤트 루프 설명

JavaScript는 단일 스레드 환경, 동기적으로 이벤트를 처리하는 메커니즘을 갖는다.

이벤트 루프란 이벤트 처리를 위한 주요한 컴포넌트로서, 이벤트 발생과 이벤트 핸들러 실행 사이의 상호작용을 관리한다.

 

일반적으로 JavaScript 코드는 순차적으로 실행되지만, 이벤트 루프를 통해 비동기적인 작업은 바로 반환되지 않고 나중에 완료될 때까지 기다리지 않고도 계속해서 다음 코드를 실행 할 수 있다.

 

이벤트 루프의 역할

1. 비동기 작업을 관리하고 완료되면 이벤트 큐에 해당 이벤트를 넣는다. 이벤트는 이벤트 큐에 순서대로 쌓이게 된다.

2. 현재 실행 중인 코드의 완료 여부를 확인하고, 실행할 다음 이벤트를 이벤트 큐에서 가져와 처리한다.

  •  이벤트 큐(Event Queue) JavaScript에서는 이벤트 루프와 동일어로도 쓰인다.
  •  비동기 이벤트 처리를 위해 사용되는 자료구조. 이벤트를 기록하고, 순차적으로 처리하는 방식으로 동작한다. 일반적으로 이벤트 큐는 이벤트가 발생하는 순서대로 큐에 저장되고, 발생한 순서대로 처리한다.

이벤트 루프의 동작 과정

1. Call Stack에 코드를 추가하여 실행한다.

2. Call Stack이 비어 있으면 이벤트 큐에서 다음 이벤트를 가져와 Call Stack에 추가한다.

3. Call Stack에 추가된 이벤트의 코드가 실행되고 Call Stack이 다시 비워질 때까지 이과정을 반복한다.

 

while(queue.waitForMessage()){
  queue.processNextMessage();
}

queue.waitForMessage() 함수는 현재 처리할 수 있는 메시지가 존재하지 않으면 새로운 메시지가 도착할 때까지 동기적으로 대기한다.

 

런타임 상황의 메모리 동작

런타임 환경에서 메모리 관리

Stack

  • 스택은 메모리의 한 영역으로, 함수 호출과 관련된 정보를 저장하는데 사용된다.
  • 함수가 호출될 때마다 Stack Frame이라는 메모리 블록이 생성되어 스택에 쌓인다.
  • 현재 실행 중인 함수의 정보, 매개변수, 로컬 변수 및 복귀 주소 등이 스택 프레임에 저장된다.
  • 함수가 실행을 완료하면 해당 함수의 Frame이 제거되고 스택의 맨 위에 있는 다음 스택 프레임이 실행된다. 이를 함수 호출 스택 (CallStack)이라고 한다.
function foo(b) {
  let a = 10
  return a + b + 11
}

function bar(x) {
  let y = 3
  return foo(x * y)
}

const baz = bar(7) // 42를 baz에 할당
  1. bar를 호출할 때, bar의 인수와 지역 변수를 포함하는 첫 번째 프레임이 생성됩니다.
  2. bar가 foo를 호출할 때, foo의 인수와 지역 변수를 포함하는 두 번째 프레임이 생성되어 첫 번째 프레임의 위로 푸시됩니다.
  3. foo가 반환하면, 맨 위의 프레임 요소를 스택 밖으로 꺼냅니다. (bar 호출 프레임만 남음)
  4. bar가 반환하면, 스택이 빕니다.

Heap

  • 힙은 동적으로 할당되는 객체 데이터를 저장하는데 사용된다. 객체와 배열 같은 자료구조들은 힙에 저장되며, 이들을 참조를 통해 접근한다.
  • 힙은 가비지 컬렉션에 의해 관리되며, 사용하지 않는 개체들은 자동으로 해제된다.

 

Queue

  • 큐는 비동기 작업의 처리를 위해 사용되는 자료구조
  • 비동기적으로 발생하는 이벤트나 작업은 이벤트 루프를 통해 큐에 추가된다.
  • 큐는 FIFO 원칙에 따라 동작하며, 새로운 이벤트는 큐의 뒤에 추가 되고 실행 할 이벤트는 큐의 앞에서 제거된다.
  • 이벤트 루프는 큐에 있는 이벤트를 순차적으로 처리하고, 해당 이벤트에 할당된 콜백 함수를 실행한다.

 

이러한 메모리 구조와 큐는 자바스크립트의 비동기적인 특성을 관리하고, 함수 호출과 객체 데이터를 저장하며, 이벤트 처리를 순서대로 처리함으로써 프로그램의 실행을 관리한다.

 

참조

 

데이터 타입의 종류

  • 기본형 primitive type
  • 숫자 number
  • 문자열 string
  • 불리언 boolean
  • null, undefined
  • ES6에서 추가된 symbol

 

  • 참조형 reference type
  • 객체 Object
  • 배열 Array
  • 함수 Fuction
  • 날짜 Date
  • 정규표현식 RegExp
  • ES6에서 추가된 Map, WeakMap, Set, WeakSet

 

기본형과 참조형을 구분하는 기준

  • 기본형(불변값) : 값이 담긴 주솟값을 바로 복제 
  • 참조형(가변값) : 값이 담긴 주솟값들로 이루어진 묶음을 가리키는 주솟값을 복제

불변값과 가변값의 의미는 아래 예제를 통해 알아보자.

 

1
2
3
4
var a;
= 'abc';
 
var a = 'abc'; //변수 선언과 할당을 한 문장으로 표현 위 2줄 코드와 같다.
cs

'기본형' 여기선(string)의 선언과 데이터 할당에 대한 메모리 영역

 

-대괄호[]의 숫자는 코드 줄을 의미-

 

[1] var a; // var 예약어로 변수 a 선언

변수 영역에서 빈 공간(@1003)을 확보한다. 확보한 공간의 식별자를 a로 지정한다.

 

[2] = 'abc'; // 변수 a에 데이터 할당

데이터 영역의 빈공간(@5004)에 문자열 'abc'를 저장한다.

변수 영역에서 a라는 식별자를 검색한다(@1003)

앞서 저장한 문자열의 주소(@5004)를 @1003의 공간에 대입한다.

 

[4] var a = 'abc'; // 변수 선언과 할당을 한 문장으로 표현

 

위 예제와 같이 변수영역엔 식별자(a)와 값이 저장된 데이터 영역의 주소(@5004)가 저장된다. 이처럼 변수 영역과 데이터 영역을 분리하면 중복된 데이터에 대한 처리 효율이 높아진다.
기본형 데이터 타입이 불변값인 이유는 'abc' 문자열에 'def'를 추가한다면 'abc'가 저장된 공간에 'def'를 더하는 것이 아닌 새로운 공간(5005)에 'abcdef'를 저장하고 1003주소의 값은 (@5004) -> (@5005)로 변경된다. 이렇게 'abc'는 변하지 않는 성질을 띄고 있다.

 

불변값을 알아 봤으니 이제 가변값도 예제를 통해 알아보자.

 

1
2
3
4
var obj1 = {
    name : 'ohsung',
    age : 26
};
cs

'참조형' 객체의 선언과 데이터 할당에 대한 메모리 영역

 

[1] var obj1 = { // var 예약어로 변수 obj를 선언

변수 영역에서 빈 공간(@1003)을 확보한다. 확보한 공간의 식별자를 obj1로 지정한다.

 

[2] name : 'ohsung'

[3] age : 26

데이터 영역의 빈공간(@5001)에 데이터를 저장하려고 보니 여러 개의 프로퍼티로 이뤄진 데이터 그룹이다.

이 그룹 내부의 프로퍼티들을 저장하기 위해 별도의 변수 영역을 마련하고, 그 영역의 주소(@7103 ~ ?)를 @5001에 저장한다.

@7103 및 @7104에 각각 name과 age라는 프로퍼티 이름을 저장한다.

데이터 영역에서 'ohsung'을 @5003에 저장하고, 26을 @5004에 저장한다.

 

기본형 데이터와의 차이는 '객체의 변수(프로퍼티) 영역'이 별도로 존재한다는 점이다. 예제를 보면 객체가 별도로 할애한 영역은 변수 영역일 뿐 '데이터 영역'은 기존의 메모리 공간을 그대로 활용하고 있다. 데이터 영역에 저장된 값은 모두 불변값이다. 그러나 변수에는 다른 값을 대입할 수 있다. 바로 이부분에 참조형 데이터는 가변값이다라고 한다.

 

  • JS로 작성한 프로그램 = script

 

  • JS특징
  1. script는 HTML 안에서 작성 할 수 있다. (HTML을 불러올 때 자동으로 실행)
  2. '컴파일 없이' 문자 형태로 작성 및 실행 가능 (인터프리터)
  3. 브라우저, 서버 뿐 아니라 '자바스크립트 엔진' 프로그램이 들어 있는 모든 디바이스에서 동작한다.
  4. 메모리나 CPU 조작을 허용하지 않는다.
  5. 브라우저엔 자바스크립트 가상 머신이란 엔진이 내장되어 있다
  6. node.js 환경에선 파일을 읽거나 쓰고, 네트워크 요청을 수행한다.

 

  • JS 강점
  1. HTML/CSS 완전한 통합 가능
  2. 간단하게 일을 처리
  3. 모든 주요 브라우저 지원, 기본 언어로 사용됨

 

 

  • 브라우저 별 JS엔진
  • V8 - chrome
  • Chakra - IE, Edge
  • SquirrelFish - safari

 

  • 브라우저에서 할 수 있는 일
  1. HTML 추가, 수정하기
  2. 마우스 클릭이나 키보드 눌림과 같은 사용자 행동에 반응하기
  3. 네트워크를 통해 원격 서버에 요청을 보내기, 파일 다운로드, 업로드하기
  4. 쿠키를 가져오거나 설정하기
  5. 클라이언트 측에 데이터 저장

 

  • 브라우저에서 할 수 없는 일
  1. 사용자가 브라우저 창에 파일을 끌어다 두거나, <input> 태그를 통해 파일을 선택할 때 같은 특정 상황에서만 파일 접근을 허용한다.
  2. 도메인, 프로토콜, 포트가 다르다면 같은 브라우저 내 다른 탭과 창에서 서로의 정보를 공유하지 않는다.
  3. 위 제약 사항들은 모두 보안을 위해 만들어졌다.

 

브라우저에서의 자바스크립트

 

 

 

 

 

+ Recent posts