프로그램과 프로세스

아키텍쳐, 컴파일러, 프로그램과 프로세스, 운영체제에 대해서 알아봅니다.
아키텍쳐, 컴파일러, 프로세스, 운영체제, 프로그램


운영체제

리눅스 운영체제의 부팅 과정리눅스 운영체제의 부팅 과정

운영체제(OS)란 윈도우즈, 리눅스, 안드로이드, iOS, MacOS 같은 일종의 거대한 프로그램입니다. 이러한 프로그램을 응용프로그램과 구분하여 시스템 프로그램이라고 말하기도 합니다.

컴퓨터에 전원을 넣으면 메인보드에 저장된 BIOS라는 프로그램이 HDD/SSD/USB 등의 보조기억장치에서 부트로더라는 프로그램을 찾아 실행합니다. 이때 부트로더는 운영체제를 실행하고 디스플레이에 예쁜 UI가 뜨게 됩니다. 운영체제가 하는 주요한 일은 다음과 같습니다.

  • 컴퓨터의 메인보드에 접속된 하드웨어들을 상호 연결하고 제어함
  • 응용프로그램이 사용 할 수 있는 서비스/라이브러리들을 제공
  • 보조 기억장치 및 주변기기를 추상화한 파일시스템을 조작 할 수 있도록 응용프로그램에 API를 제공
  • 네트워킹을 추상화하여 응용프로그램에 API를 제공
  • 공통적인 GUI를 쉽게 만들 수 있게 추상화하여 응용프로그램에 API를 제공
  • 응용프로그램의 실행, 멀티태스킹을 위한 스케쥴링
  • 컴퓨터의 보안과 사용자 계정을 관리

여기서 API는 운영체제가 개발자들을 위해 미리 높은 추상화 수준으로 준비해 놓은 코드의 집합이라고 볼 수 있습니다.

프로그램

어셈블리와 기계어(CPU 인스트럭션 스트림)어셈블리와 기계어(CPU 인스트럭션 스트림)

프로그램은 CPU에 종속된다

프로그래밍 언어가 등장하기 이전, 컴퓨터 발전의 초창기에는 CPU의 기능들(산술 연산 및 입출력 등)을 숫자 하나 하나에 맵핑하여두고 이러한 숫자들, 즉 명령어 또는 기계어 (Instruction)를 목적에 맞게 순서대로 나열한 것이 프로그램이었습니다. 하지만 이진수로 코드를 작성하는 것을 좀 더 사람이 이해하기 쉽도록 하기위해서 명령어들에 숫자 대신 문자열을 맵핑하여 조금 더 사람이 이해하기 쉽게 한 것을 어셈블리어라고 합니다.

기계어에서 고수준 언어까지기계어에서 고수준 언어까지

C언어로 작성한 소스코드C언어로 작성한 소스코드

추상화는 IT의 모든 곳을 관통하고 있습니다. 어셈블리어에서 한단계 더 나아가 고수준 언어라고 불리는 사람이 이해하기 쉬운 C언어 같은 프로그래밍 언어들이 등장합니다. 이때 프로그래밍 언어로 작성된 소스코드는 단순한 텍스트 파일입니다. 따라서 소스코드는 특정 인코딩을 따라 문자들을 나열한 것에 불과합니다.

저수준 프로그램의 컴파일 과정저수준 프로그램의 컴파일 과정

이 단순한 텍스트를 다시 기계어로 표현해야만 CPU가 이해 할 수 있는 프로그램이 됩니다. 이렇게 소스코드를 다시 기계어로 번역하는 과정을 컴파일이라고 합니다. 물론 프로그래밍 언어에 따라 저마다의 컴파일러가 필요합니다.

C언어 소스코드를 번역한 기계어(좌) 어셈블리(우)C언어 소스코드를 번역한 기계어(좌) 어셈블리(우)

이 때 생각 해볼 점은 CPU를 생산하는 기업이나 제품이 한가지가 아니라는 점입니다. Intel은 x86, x64 등의 아키텍쳐를 설계하여 CPU를 생산하고 있습니다. 또 모바일 기기에 쓰이는 ARM CPU 제품군은 ARM이라는 아키텍쳐를 쓰고 있습니다. 이러한 여러 CPU 간에 서로 다른 아키텍쳐(명령어 집합)를 쓰기 떄문에 프로그램은 CPU의 아키텍쳐에 종속됩니다.

명령어 집합(영어: instruction set) 또는 명령어 집합 구조(영어: Instruction set architecture, ISA)는 마이크로프로세서가 인식해서 기능을 이해하고 실행할 수 있는 기계어 명령어를 말한다. 마이크로프로세서마다 기계어 코드의 길이와 숫자 코드가 다르다. 명령어의 각 비트는 기능적으로 분할하여 의미를 부여하고 숫자화한다. 프로그램 개발자가 숫자로 프로그램하기가 불편하므로 기계어와 일대일로 문자화한 것이 어셈블리어이다. … (위키백과)

프로그램은 운영체제에 종속된다

프로그램은 운영체제에 종속프로그램은 운영체제에 종속

프로그램을 메모리에 복사하면서 로드하고, 프로그램에 필요한 공유 라이브러리를 로드하고, 멀티태스킹을 위해 CPU와 메모리 등의 자원을 분배하는 등의 다양한 일들은 운영체제가 담당하고 있습니다. (지금 여기서 모든 용어를 명확히 알 필요는 없습니다.)

따라서 운영체제들은 프로그램의 실행을 위해 저마다의 파일 포맷을 정해 놓고 있습니다. 프로그램을 실행하는 운영체제라는 프로그램이 읽고 쓰는 파일 포맷이 저마다 다른 것입니다. 여기서 또 프로그램은 운영체제에 종속됩니다. 리눅스에서 컴파일한 프로그램은 윈도우즈에서 실행되지 않습니다. 하지만 리눅스에서 작성한 소스코드를 윈도우즈에서 컴파일한다면 잘 작동합니다.

프로세스

리눅스 프로세스의 구조리눅스 프로세스의 구조

보조기억장치에 저장된 프로그램이 운영체제를 통해 실행되면 프로그램의 기계어들과 데이터 등이 메모리상에 복사되면서 CPU의 처리 대상이 됩니다. 이렇게 숨결이 들어간 프로그램을 프로세스(Process)라고 부릅니다. 프로그램을 개발하는 과정에선 프로세스의 메모리에 이 순간엔 어떤 데이터가 있고 또 저 순간엔 어떤 데이터가 있는지, 그 흐름을 상상하면서 코드를 작성하게 됩니다. 메모리상에 프로세스의 구조에 대해 간단히 알아 보겠습니다.

  • text
    기계어로 표현된 프로그램의 로직들

  • data
    프로그램을 작성할 때 지정된 값들

  • heap
    런타임(Runtime)에 동적으로 생성되는 값들

  • stack
    함수라고 불리는 프로그램의 반복적인 로직이 실행되고 소멸되는 공간

요약

  • 아키텍쳐, 명령어 집합
    CPU가 처리 할 수 있는 단순한 명령어(기계어)들의 집합으로 하드웨어 수준에서 설계 됨

  • 소스코드
    사람이 이해하기 쉬운 프로그래밍 언어로 프로그램의 작동을 묘사한 텍스트 파일

  • 컴파일, 컴파일러
    소스코드를 기계어로 번역하는 과정, 그리고 번역을 담당하는 프로그램

  • 프로그램
    운영체제와 CPU에 종속적인 실행 가능한 파일

  • 프로세스
    운영체제가 메모리에 프로그램을 복사하여 CPU가 처리중인 (실행중인) 프로그램

목차
2. 프로그래밍 연습
저자

김동욱

개발 경력 약 10년, 전문 분야는 웹 및 각종 응용 소프트웨어 플랫폼입니다. Codeflow를 운영하고 있습니다.

2018년 04월 06일 업데이트

지원되지 않는 웹 브라우저거나 예기치 않은 오류가 발생했습니다.