Shell : 사용자가 커널을 직접 다루기 너무 어려워 응용 소프트웨어로 간편한 제어 및 사용 제공
그 외 모든 응용 소프트웨어 : 사용자가 다운, 설치 받아 사용하는 모든 것
03. 프로그램, 프로세스, 스레드
#1. 프로그램
프로그램은 디스크에 저장된 정적인 코드를 말한다.
#2. 프로세스
프로세스는 실행중인 프로그램이다.
실행 단위가 크고, 한 개의 프로그램에 한 개의 프로세스만 존재한다.
독립된 메모리 공간을 가지며, 서로 다른 프로세스 간에는 직접적인 메모리가 공유되지 않는다.
#3. 스레드
스레드는 실행 단위가 작고, 한 개의 프로그램 내 수많은 스레드가 존재 가능하다.
스레드마다 프로그램 카운터(실행 위치) + 명령어 레지스터(실행 함수) + 스택 영역(실행 변수)를 가진다.
스택은 스레드마다 독립적으로 할당되며, 함수 호출시 사용되는 지역 변수, 반환 주소등의 정보가 저장된다. 힙은 프로세스마다 하나씩 할당되며, 동적으로 할당되는 메모리 공간이다. 모든 스레드가 이 힙 공간을 공유한다.
04. 운영체제 위 어플리케이션 동작 원리
#1. 운영체제 부팅과 초기화 프로세스
💡 운영체제(커널)의 부팅
컴퓨터가 부팅되면, 가장 먼저 운영체제의 핵심 부분인 커널이 로드된다.
커널이 로드되면 하드웨어를 제어할 수 있는 권한을 가지며, 시스템의 기본적인 동작을 시작한다.
💡 초기화 프로세스
커널 부팅이 완료된 후, 초기화 프로세스가 시작된다.
초기화 프로세스는 시스템에서 가장 먼저 실행되는 프로세스로, 다른 모든 프로세스의 시작점이다.
이 프로세스는 항상 PID1을 부여 받는다.
초기화 시스템은 시스템의 기본 설정 파일, 구성 파일을 읽고, 이 설정 및 구성에 따라 필요한 서비스와 프로세스를 자동으로 시작한다.
#2. 초기화 시스템
초기화 시스템은 운영체제에서 부팅 후, 프로세스와 서비스를 관리하는 시스템이다.
리눅스에서 사용되는 초기화 시스템에는 SysVInit과 SystemD가 존재한다.
◼︎ SysVInit
전통적인 초기화 시스템으로, Unix와 초기 리눅스 배포판에서 사용한다.
'init'이라는 프로세스 이름으로 실행되며, 프로세스를 시작한 후에는 이들을 추적하지 않는다.
개별 서비스의 상태를 추적하지 않기 때문에, 프로세스가 종료되거나 문제가 생겨도 관리가 어렵다.
service (start / stop / restart) ← /etc/init.d
◼︎ SystemD
현대적인 초기화 시스템으로, 현재 대부분의 리눅스 배포판(Ubuntu 등)에서 사용된다.
'systemd'라는 이름으로 실행되며, 시스템 부팅 후에도 계속 실행되어 프로세스를 추적하고 관리할 수 있다.
개별 서비스의 상태를 지속적으로 모니터링하고 관리할 수 있어 안정성이 높다.
한 번 수행 후 계속 Daemon 형태로 떠있어서 이후 개별 프로세스 추적이 가능하다.
systemctl (start / stop / status / restart) ← /etc/systemd/system/.service
💡 데몬(Daemon)
프로세스는 두가지 형태로 존재한다.
Foreground Process : 사용자가 직접 실행하는 프로세스. 부모 프로세스 존재
Background Process : 백그라운드에서 실행되는 프로세스. 부모 프로세스가 없는 상태로 독립적으로 동작
데몬은 리눅스에서 백그라운드에서 실행되는 프로세스이다.
리눅스에서 끝에 d가 붙는 sshd, httpd, mysqld와 같은 프로세스들은 모두 데몬을 뜻한다.
05. 컴파일 / 인터프리트(런타임) 과정 : 어플리케이션 개발 / 구동 방식
프로그램이 동작하는 기본 원리는 기계어가 머신에서 해석되어 실행되는 것이다.
기계어는 컴퓨터의 CPU가 직접 실행할 수 있는 코드로, 모든 프로그램은 최종적으로 이 기계어로 변환되어야 컴퓨터에서 실행될 수 있다.
기계어를 프로그램(정적)이라 하고, CPU 및 메모리가 할당되어 실행되면 프로세스(동적)이라고 한다.
#1. 컴파일 과정
컴파일 과정에서는 프로그래밍 언어로 작성된 코드를 컴퓨터가 이해할 수 있는 기계어로 변환한다.
◼︎ Java의 경우
Java 소스 코드(.java 파일)는 자바 컴파일러(javac)에 의해 바이트코드(.class 파일)로 변환된다.
바이트 코드는 기계어가 아니며, 자바 가상 머신(JVM)이 이해할 수 있는 중간 형태의 코드이다.
◼︎ C, C++의 경우
C, C++ 소스 코드(.c, .cpp 파일)는 GNU 컴파일러(GCC)나 LLVM 컴파일러를 통해 직접 기계어(바이너리 코드)로 컴파일한다.
이 기계어는 특정 머신(컴퓨터)에서 바로 실행될 수 있다.
#2. 런타임 과정
런타임 과정은 이미 컴파일된 코드가 실제로 실행된다.
바이트코드(.class 파일)는 JVM에 의해 실행된다. 이 과정에서 JVM은 바이트 코드를 기계어로 변환하여 실행하고, 이 변환 과정을 인터프리트라 한다. 이 방식은 JVM만 해당 시스템에 맞춰 설치하면 되기 때문에 Java 프로그램은 여러 종류의 컴퓨터에서 동일한 바이트코드를 실행할 수 있다.
💡 컴파일 에러
컴파일 에러는 컴파일 과정에서 발생하는 오류이다.
소스 코드의 문법이 잘못되었을 때 발생할 수 있으며, 컴파일러가 코드를 기계어로 변환하지 못해 프로그램은 실행되지 않는다.
운영체제 개요 및 어플리케이션 동작 원리
01. 하드웨어 : 어플리케이션이 동작하는 머신
02. 소프트웨어 : 시스템 소프트웨어 + 응용 소프트웨어
03. 프로그램, 프로세스, 스레드
#1. 프로그램
프로그램은 디스크에 저장된 정적인 코드를 말한다.
#2. 프로세스
프로세스는 실행중인 프로그램이다.
실행 단위가 크고, 한 개의 프로그램에 한 개의 프로세스만 존재한다.
독립된 메모리 공간을 가지며, 서로 다른 프로세스 간에는 직접적인 메모리가 공유되지 않는다.
#3. 스레드
스레드는 실행 단위가 작고, 한 개의 프로그램 내 수많은 스레드가 존재 가능하다.
스레드마다 프로그램 카운터(실행 위치) + 명령어 레지스터(실행 함수) + 스택 영역(실행 변수)를 가진다.
04. 운영체제 위 어플리케이션 동작 원리
#1. 운영체제 부팅과 초기화 프로세스
💡 운영체제(커널)의 부팅
컴퓨터가 부팅되면, 가장 먼저 운영체제의 핵심 부분인 커널이 로드된다.
커널이 로드되면 하드웨어를 제어할 수 있는 권한을 가지며, 시스템의 기본적인 동작을 시작한다.
💡 초기화 프로세스
커널 부팅이 완료된 후, 초기화 프로세스가 시작된다.
초기화 프로세스는 시스템에서 가장 먼저 실행되는 프로세스로, 다른 모든 프로세스의 시작점이다.
이 프로세스는 항상 PID1을 부여 받는다.
초기화 시스템은 시스템의 기본 설정 파일, 구성 파일을 읽고, 이 설정 및 구성에 따라 필요한 서비스와 프로세스를 자동으로 시작한다.
#2. 초기화 시스템
초기화 시스템은 운영체제에서 부팅 후, 프로세스와 서비스를 관리하는 시스템이다.
리눅스에서 사용되는 초기화 시스템에는 SysVInit과 SystemD가 존재한다.
◼︎ SysVInit
전통적인 초기화 시스템으로, Unix와 초기 리눅스 배포판에서 사용한다.
'init'이라는 프로세스 이름으로 실행되며, 프로세스를 시작한 후에는 이들을 추적하지 않는다.
개별 서비스의 상태를 추적하지 않기 때문에, 프로세스가 종료되거나 문제가 생겨도 관리가 어렵다.
◼︎ SystemD
현대적인 초기화 시스템으로, 현재 대부분의 리눅스 배포판(Ubuntu 등)에서 사용된다.
'systemd'라는 이름으로 실행되며, 시스템 부팅 후에도 계속 실행되어 프로세스를 추적하고 관리할 수 있다.
개별 서비스의 상태를 지속적으로 모니터링하고 관리할 수 있어 안정성이 높다.
한 번 수행 후 계속 Daemon 형태로 떠있어서 이후 개별 프로세스 추적이 가능하다.
💡 데몬(Daemon)
프로세스는 두가지 형태로 존재한다.
데몬은 리눅스에서 백그라운드에서 실행되는 프로세스이다.
리눅스에서 끝에 d가 붙는 sshd, httpd, mysqld와 같은 프로세스들은 모두 데몬을 뜻한다.
05. 컴파일 / 인터프리트(런타임) 과정 : 어플리케이션 개발 / 구동 방식
프로그램이 동작하는 기본 원리는 기계어가 머신에서 해석되어 실행되는 것이다.
기계어는 컴퓨터의 CPU가 직접 실행할 수 있는 코드로, 모든 프로그램은 최종적으로 이 기계어로 변환되어야 컴퓨터에서 실행될 수 있다.
기계어를 프로그램(정적)이라 하고, CPU 및 메모리가 할당되어 실행되면 프로세스(동적)이라고 한다.
#1. 컴파일 과정
컴파일 과정에서는 프로그래밍 언어로 작성된 코드를 컴퓨터가 이해할 수 있는 기계어로 변환한다.
◼︎ Java의 경우
Java 소스 코드(.java 파일)는 자바 컴파일러(javac)에 의해 바이트코드(.class 파일)로 변환된다.
바이트 코드는 기계어가 아니며, 자바 가상 머신(JVM)이 이해할 수 있는 중간 형태의 코드이다.
◼︎ C, C++의 경우
C, C++ 소스 코드(.c, .cpp 파일)는 GNU 컴파일러(GCC)나 LLVM 컴파일러를 통해 직접 기계어(바이너리 코드)로 컴파일한다.
이 기계어는 특정 머신(컴퓨터)에서 바로 실행될 수 있다.
#2. 런타임 과정
런타임 과정은 이미 컴파일된 코드가 실제로 실행된다.
바이트코드(.class 파일)는 JVM에 의해 실행된다. 이 과정에서 JVM은 바이트 코드를 기계어로 변환하여 실행하고, 이 변환 과정을 인터프리트라 한다. 이 방식은 JVM만 해당 시스템에 맞춰 설치하면 되기 때문에 Java 프로그램은 여러 종류의 컴퓨터에서 동일한 바이트코드를 실행할 수 있다.
💡 컴파일 에러
컴파일 에러는 컴파일 과정에서 발생하는 오류이다.
소스 코드의 문법이 잘못되었을 때 발생할 수 있으며, 컴파일러가 코드를 기계어로 변환하지 못해 프로그램은 실행되지 않는다.
💡 런타임 에러
런타임 에러는 프로그램이 실행 중에 발생하는 오류이다.
잘못된 연산, 배열의 경계를 넘어선 접근 등이 런타임 중에 발생할 수 있는 에러이다.
'ASAC > 웹 기초 프로그래밍' 카테고리의 다른 글