나의 1번째 공부 기록공간 - 기본 Part : 운영체제 (1)

BE_{Potato.}·2023년 1월 26일
0

내가 나를 돌이켜보면 무엇을 하던지 그 중심에 있는 핵심본질들을 파악해 이것으로 그 문제들을 해결하려는 성격인 것 같다.

개발자의 길을 걸어가면서도 내 이런 성격이 발동해서 이 쪽 분야의 핵심본질은 무엇일까를 고민을 많이 했다. 부트캠프에서는 배우는 것들은 프레임워크와 기술에 치우쳐진 느낌이 많았는데 나는 항상 그것보다 더 중요한 근본이 있을 것이라 생각했다. 몇 주간의 연구결과 컴퓨터공학 지식이 그 근본에 해당한다는 것을 파악했고 이것에 시간을 들여 흔들리지 않는 내 기본실력을 만들어내야 한다는 생각이 들었다.
컴퓨터 공학의 모든 과목을 다 볼 수는 시간적으로 없기에 백엔드 실무에 가장 필요한 필수과목들의 기본을 다지는 것이 우선이라 생각이 들었다.
운영체제, 자료구조와 알고리즘, 데이터베이스, 네트워크, 컴퓨터구조가 이에 해당될 것 같고, 운영체제를 먼저 공부 할 것이다.
왜 운영체제를 먼저 공부하게 되었냐고 하면
운영체제의 원리를 알게 되면 한줄 요약하자면, 버그와 각종 문제들을 만났을 때 이를 해결할 수 있는 근본이 되기 때문이다. 그리고 운영체제를 알면 성능 면에서도 좀 더 다각도로 볼 수 있다.

인프런에서 운영체제 강의를 설날 전에 찾아서 두번 정도 가볍게 돌려봤는데 처음 들어보는 것이라 첫번째 들을 때에는 어렵긴 했다.
이제 본격적으로 운영체제에서 공부한 내용들을 기록해나가려고 한다.


< 운영체제 개요 >

컴퓨터는 운영체제 없이 돌아가는가? 그렇다.
하지만, 설계한 그대로로만 돌아가고 다른 기능은 안 된다.
예시로 전화기와 스마트폰을 비교하면 이해하기 쉽다.

< 운영체제가 하는 일 >

  1. 프로세스 관리(컴퓨터로 노래와 게임,웹서핑을 동시에 실행할 수 있다.)
  2. 메모리 관리(모든 프로그램은 메모리 위에서 실행된다.)
  3. 하드웨어 관리 : 운영체제가 사용자의 직접적인 하드웨어 접근을 막는다.
  4. 파일 시스템 관리

< 운영체제의 역사 >

1940년대 - 애니악 개발. 하드웨어 비용이 비싸서 어떻게 하면 CPU를 많이 쓸 수 있을까를 고민함
1950년대 초반 - 직접회로를 개발하고 현대 모습의 컴퓨터가 탄생함.
1950년대 중후반 - '싱글스트림 배치시스템'을 개발함.
I/O 디바이스 관리자 만들어 CPU 쉬지 않게 만듬. 하지만 I/O에도 CPU를 기다려야 하는 경우도 있다.
1960년대 - '시분할 시스템' 개발(여러 작업을 가능하게 시간을 나눠서 실행되게). 파일 시스템이 등장했음.
+UNIX 운영체제의 등장(멀티프로그래밍,다중사용자,파일시스템 제공) => 이 때 메모리 침범 이슈가 생김.
1970년대 - 개인컴퓨터(애플의 매킨토시,마소의 MS-DOS) 출시

  • 정리하자면
    CPU 사용률와 비용절감 문제 때문에 '운영체제'가 탄생!

< 운영체제의 핵심 >

  • 커널이 운영체제의 핵심. 커널은 프로세스/메모리/저장장치를 관리하는 핵심적인 기능을 담당함.
    이 커널은 사용자가 직접 접근이 불가능함(인터페이스로 GUI/CLI를 제공해 사용자가 이를 이용함)
  • 어플리케이션은 '시스템 콜'을 통해서 커널에 접근 가능함.
    시스템 콜은 사용자와 app으로부터 보호해줌.
  • 하드웨어는 '드라이버'를 통해 커널과 연결됨

< 컴퓨터 >

  • 현재 컴퓨터는 프로그램 내장방식인 '폰 노이만' 구조를 채택함.
    CPU와 메모리를 두고 둘 사이를 버스(데이터를 전달하는 통로)로 연결
  • 하드웨어의 기본은 메인보드. 여기에 기기들이 연결된다.

< CPU의 구조 >

중앙처리장치라는 뜻이며,

  1. 제어장치(모든 장치들의 동작을 제어하고 지시)
  2. 산술논리 연산장치(데이터 연상을 담당함)
  3. 레지스터(CPU 내에서 계산을 위해 임시로 보관하는 장치.변수)

세가지로 이루어져있다.

< 메모리 종류 >

RAM(메인 메모리로 사용)
ROM(데이터를 한번 쓰면 수정불가하기 때문에 부팅과 관련된 BIOS를 저장함)

< 컴퓨터 부팅과정 >

  • 바이오스가 주요장치 이상여부 확인
  • 이상 없다면 부트로더 실행
  • 운영체제를 메모리로 불러오고 부팅이 됨.

< 인터럽트 >

  • CPU가 입출력(I/O) 관리자한테 주기적으로 입출력 확인 => 폴링 방식. 성능이 안 좋음.

=> 인터럽트 방식을 만듬.
'인터럽트'는 CPU가 입출력 관리자에게 입출력 명령 내리고,다른 작업을 한다. 입출력 관리자가 입출력 완료되었을 때 CPU에 신호를 주고 인터럽트 서비스루틴(ISR) 실행시켜 작업을 완료함.

  • 인터럽트는 '하드웨어 인터럽트/소프트웨어 인터럽트'가 있다.

< 프로그램/프로세스 >

  • 프로그램이란? 하드디스므 등에 저장된 명령문의 집합체(어플리케이션이라고도 부름)

  • 프로세스란? 실행 중인 프로그램을 말함.
    하드디스크에 있던 프로그램이 메모리에 올라간 것.

  • 프로그램은 하드디스크만 이용하는 수동적인 존재.
    프로세스는 메모리도 쓰고, CPU도 쓰고 필요에 따라 입/출력도 하기 때문에 능동적인 존재.

< 프로세스의 구조 >

-코드영역: 자신을 실행하는 코드가 저장됨.
-데이터영역: 전역변수와 static(정적)변수가 저장되어 있음.
-스택영역: 지역변수와 함수 호출 시에 필요한 정보들이 저장됨.
-힙 영역: 프로그래머가 동적으로 메모리를 할당하는 데에 쓰인다.

< 컴파일 과정 >

.c -> 전처리기 -> .i -> 컴파일러 -> 어셈블리어로 변경(.s) -> 어셈블러 -> 기계어로 변경(.o) -> 링커 -> 링킹

< 멀티프로그래밍/멀티프로세싱 >

-유니프로그래밍: 메모리에 하나의 프로세스가 올라간 것을 말함.
멀티프로그래밍: 메모리에 여러개의 프로세스가 올라간 것.(
메모리의 관점)
멀티프로세싱: (CPU관점) CPU가 여러개의 프로세스를 처리하는 것.

  • 오늘날 운영체제는 멀티프로그래밍/멀티프로세싱이 공존함.
    -과거에는 메모리가 작아서 멀티프로그래밍이 안 됐음.=> 스와핑 이용해서 작업함.
    ○ 스와핑: 메모리에 있는 데이터를 다른 저장장치로 보내고, 다른 저장장치의 데이터를 메모리로 보내는 것.

< PCB >
-운영체제는 프로세스들을 전부 관리하고, 공평하게 실행시켜야 함.
프로세스가 실행되면 해당 프로세스의 정보를 가진 PCB를 만들고 저장.

-PCB는 연결리스트라는 자료구조로 저장됨.(PCBa-PCBb-PCBc)
-운영체제는 프로세스가 종료되면 해당 PCB를 제거, 남은 PCB는 연결리스트구조 유지

< PCB의 구조 >
-포인터: 부모와 자식프로세스에 대한 포인터. 할당된 자원에 대한 포인터 등... 효율적인 접근을 위해 포인터 사용.
-프로세스 상태: 현재 프로세스의 5가지 상태를 나타냄
(생성-준비-실행-대기-완료)
-프로세스 ID: 프로세스를 식별하기 위한 숫자.
-프로그램 카운터:다음에 실행될 명령어의 주소를 포함하는 프로그램 카운터를 저장. '시분할 시스템' 다시 시작할 때에 프로그램 카운터가 꼭 필요함.
-레지스터 정보: 프로세스가 실행될 때 사용했던 레지스터 값들이 저장됨(프로그램 카운터와 비슷한 용도)
-메모리 관련 정보
-CPU스케줄링 정보
-etc...

< 프로세스 상태 >

  • 시분할 시스템 -> 한번에 하나의 프로세스를 다루는데, 돌아가는 시간이 너무 빨라서 보이기엔 동시에 시작되는 것처럼 보임.
    시분할 처리를 위한 프로세스의 5가지 상태를 프로세스 상태라 함.

-생성:PCB를 생성하고 메모리에 프로그램 적재를 요청한 상태
-준비:승인을 받으면, CPU를 사용하기 위해 기다리고 있는 상태
-실행:준비상태 프로세스가 CPU스케줄러에 의해 CPU할당받아 실행되는상태-> 실행상태의 프로세스의 수는 CPU의 갯수 만큼.
-대기:프로세스가 입출력을 하면 입출력이 완료될 때까지 기다리는 상태
CPU는 굉장히 빠른데,입출력은 상대적으로 느림.'입출력 요청을 한 프로세스'
-완료:프로세스가 종료된 상태.프로세스가 사용했던 데이터를 메모리에서 제거하고, 생성된 PCB도 제거함.

< 컨텍스트 스위칭 >

  • 프로세스가 실행되는 중에 다른 프로세스를 실행하기 위해서 실행 중인 프로세스 상태를 저장하고, 다른 프로세스의 상태값으로 교체하는 작업.
    -> 컨텍스트 스위칭이 일어날 때 PCB의 내용이 변경됨->CPU 값이 다시 세팅됨.(프로세스 상태, 프로그램 카운터, 각종 레지스터값...)
  • 인터럽트가 발생하면 CPU 세팅을 함. 다음 실행시킬 프로세스의 레지스터 값으로 CPU 세팅(프로그램 카운터 덕분에 바로 실행이 가능)
  • 컨텍스트 스위칭이 발생하는 이유? 다양한데, CPU 점유시간이 다 되거나 I/O 요청이 있거나 다른 종류의 인터럽트가 있을 때 발생.

< 프로세스 생성과 종료 >

  • 프로세스의 생성: 프로그램을 실행시키면 해당 프로그램의 코드영역과 데이터영역을 메모리에 로드함.-> 빈 스택과 힙을 만들어 공간 확보.-> 이 프로세스를 관리하기 위해 PCB 만들어서 값을 초기화함.

위의 과정은 부팅되소 0번 프로세스 만들 때에만 실행됨.
다른 프로세스들은 0번 프로세스 복사해서 사용한다(더 빠름)- 자식/부모 프로세스가 생김.
-exec() 함수로 원하는 값을 덮어씌움.
자식 프로세스가 종료되고 신호를 줘서 부모프로세스가 종료되는 것이 선순서인데, 꼬여서 메모리에 계속 살아있는 상태를 '좀비프로세스'라 한다.
-> 컴퓨터 껐다켜서 초기화시켜야 함.

< 쓰레드 >

  • 프로세스 수가 늘어나면 PCB가 늘어가 무거워짐(메모리를 너무 많이 차지함)
    => 그래서 고안된 것이 '쓰레드!"
    : 프로세스 내에 1개 이상이 있을 수 있고 여러개가 가능하다.
    이 쓰레드는 PCB 내의 코드,데이터,힙영역을 공유하는데 스택영역은 공유하지 않는다.쓰레드마다 각각 하나씩 보유한다.-> 메모리 절약이 많이 됨.

  • 이제 운영체제가 관리하는 단위는 프로세스 내의 쓰레드가 됨.

< 프로세스와 쓰레드의 비교 >

  • 안정성 : 프로세스 > 쓰레드 (프로세스는 서로 독립적이기 때문)
  • 속도와 자원: 쓰레드 > 프로세스(프로세스는 IPC통신으로 오버헤드가 커서 속도가 느리다.)

-쓰레드는 공유공간 내에서 문제가 생길수 있는데 이는 나중에 '프로세스 동기화'쪽에서 알아본다.

profile
항상 '기본'을 중요시하는 예비 백엔드개발자입니다!

0개의 댓글