이 글의 사진과 내용은 공룡책 과 컴퓨터학부 수업인 운영체제 강의자료를 기반으로 작성했습니다.
프로세스
란 실행 중인 프로그램(program in execution)을 뜻한다.
Memory
에 올라가서 실행되기 시작하면 비로소 생명력을 갖는 프로세스가 되며, 프로세스는 CPU를 반환하고 입출력 작업을 수행하기도 한다.프로그램은 “a set of data associated with that code”을 뜻한다.
Code, Program, and Process
Process Creation: A Little More Detail
실행
(Running)상태는 프로세스가 (1)해당 프로세스를 수행하기 위해 필요한 모든 리소스를 갖고 있고, (2)CPU에 대한 권한이 있다.
CPU 권한이 없을 때 Ready 상태로 이동한다.
필요한 정보가 충분하지 못한 상태(I/O 작업이 시작할때)인 경우 Blocked로 이동한다.
준비
(Ready)상태는 (1)해당 프로세스를 수행하기 위해 필요한 모든 리소스는 갖고 있지만, (2)CPU에 대한 권한이 없다.
봉쇄
(Blocked, Wait)상태는 해당 프로세스를 수행하기 위한 필요한 모든 리소스를 갖고 있지 못하고, CPU에 대한 권한도 없다.(ex. 입출력 작업이 진행 중인 경우)
시작
(New)상태는 프로세스을 위한 PCB가 생성되었지만 아직 충분한 리소스를 할당받지 못한 상태이다.(메모리 획득을 승인받지 못한 상태)
종료
(Terminated)상태는 프로세스가 작업을 완료하여 메모리 자원을 반납하고 PCB가 삭제된 상태이다.
실행시킬 프로세스를 변경하기 위해 원래 수행 중이던 프로세스의 문맥을 저장하고 새로운 프로세스의 문맥을 세팅하는 과정을 문맥교환
(context switch)이라고 한다.
예를 들어, 실행 상태에 있던 프로세스가 입출력 요청 등으로
봉쇄 상태로 바뀌는 경우를 들 수 있다.
이때 준비 상태에 있는 프로세스들 중에서
CPU를 할당받을 프로세스를 선택한 후
실제로 CPU의 제어권을 넘겨받는 과정을 CPU 디스패치(dispatch)라고 한다.
그 밖에 상태들
일정기간 exit된 프로세스를 OS가 관리하는 경우를 Zombie
상태라고 한다.
자식 프로세스가 종료되기 전에 부모 프로세스가 종료된 상태를 Orphan
상태라고 한다.
메인 메모리의 용량이 실행해야 하는 더 많은 프로세스를 로드하기에 충분하지 않은 경우 Swapping
을 사용한다.
메모리 공간 확보
를 위해 필요에 의해서 메인 메모리에 있는 프로세스 일부를 디스크에 내려보내는 것을 말한다.Suspend vs Preemption
Suspend : 메모리 공간이 부족해서 급한 것부터 처리하기 위해서 메인 메모리에 있는 Ready 또는 Blocked(Wait)에 있는 것들을 디스크로 내려 보내는 것을 말한다.
Preemption: Running state에서 Ready state로 가는 것을 말한다. (현재 수행되고 있는 것을 멈춘다)
Swap Out : 메모리 -> 디스크
Swap In : 디스크 -> 메모리
프로세스 제어블록
(Process Control Block: PCB)이란 OS가 시스템내의 프로세스들을 관리하기 위해 프로세스마다 유지하는 정보들을 담는 커널 내의 자료구조를 뜻한다.
쉽게 말해, 기본 프로세스에 대한 정보를 갖고 있는 자료구조이다.
프로세스 상태 관리와 문맥 교환을 위해 필요하다.
PCB는 프로세스 생성시 만들어지며 메모리에 유지된다.
PID(Process Identification Number)
Process state (running, blocked, ready) : CPU를 할당해도 되는지 여부이다.
Program counter : 다음에 수행할 명령어의 위치를 가리킨다.
CPU registers : CPU 연산을 위해 현 시점에 레지스터에 어떤 값을 저장하고 있는지를 나타낸다.
Sheduling information : CPU 스케줄링을 위한 필요한 정보이다.
Memory management information : 메모리 할당을 위해 필요한 정보이다.
I/O status information : 프로세스가 오픈한 파일 정보 등 프로세스의 입출력 관련 상태 정보를 나타낸다.
Accounting informaion : 사용자에게 자원 사용 요금을 계산해 청구하는 용도이다.
Program counter와 CPU registers는 “context”에 해당한다.
문맥교환이란 하나의 사용자 프로세스로부터 다른 사용자 프로세스로 CPU의 제어권이 이양되는 과정을 뜻한다.
문맥교환은 타이머 인터럽트가 발생하는 경우 외에 실행 중이던 프로세스가 입출력 요청이나 다른 조건을 충족하지 못해 CPU를 회수당하고 봉쇄 상태가 되는 경우에도 발생할 수 있다.
시스템이 부팅된 후 최초의 프로세스는 OS가 직접 생성하지만 그다음부터는 이미 존재하는 프로세스가 다른 프로세스를 복제, 생성하게 된다.
이때 프로세스를 생성한 프로세스를 부모
프로세스라고 하고, 새롭게 생성된 프로세스를 자식
프로세스라고 한다.
즉, 부모 프로세스가 자식 프로세스를 생성하게 되는 것이다.
이러한 방식을 통해 프로세스는 족보와 같은 계층을 형성하게 된다.
프로세스의 세계에서는 자식이 먼저 죽고, 이에 대한 처리는 자식을 생성했던 부모 프로세스가 담당하는 방식으로 진행된다.
즉, 부모 프로세스는 자식 프로세스들을 연쇄적으로 종료시킨 후에야 종료될 수 있다.
즉, 프로세스 ID(pid)를 제외한 모든 정보를 그대로 복사하는 방법을 사용한다. 따라서 부모 프로세스와 자식 프로세스는 비록 주소 공간을 따로 갖게 되지만 주소 공간 내에는 동일한 내용을 가지게 된다.
fork()를 통해 생성된 자식 프로세스는 exec() 시스템 콜을 통해 새로운 프로그램으로 주소 공간을 덮어씌울 수 있다.
이때 부모 프로세스에서는 자식 pid가 반환되고 자식 프로세스
에서는 0이 반환된다. 만약 fork() 함수 실행이 실패하면 -1을 반환한다.
첫번째 예시( int main() )
위에서 자식 프로세스는 fork() 함수의 반환값이 0이라고 했다.
따라서 pid 가 0일 때는(child) x가 1증가해 “child: x=2”이 출력된다.
부모 프로세스는 자식 pid를 받으므로, 0이 아니기 때문에 “parent: x=0”이 출력된다.
두번째 예시( void fork2() )
fork()를 할 때마다 자식 프로세스가 생성되는 것을 확인할 수 있다.
정리하자면, fork() 반환 결과가 0이라면 자식 프로세스
이고 0이 아니면(자식프로세스의 id를 가질것) 부모 프로세스
이다.
이 글의 사진과 내용은 공룡책 과 컴퓨터학부 수업인 운영체제 강의자료를 기반으로 작성했습니다.
Processor와 Memory 부분이 컴퓨터 내부장치에 해당하고, 입출력 장치을 컴퓨터 외부장치라 부른다.
컴퓨터는 외부장치에서 내부장치로 데이터를 읽어와 각종 연산을 수행한 후, 그 결과를 외부장치로 다시 내보내는 방식으로 업무를 처리한다.
이때 컴퓨터 내부로 데이터가 들어오는 것을 입력(input)
이라 하고, 컴퓨터 외부 장치로 데이터가 나가는 것을 출력(output)
이라고 한다.
메모리 및 입출력 장치 등의 각 하드웨어 장치에는 컨트롤러
라는 것이 붙어 있다.
컨트롤러는 각 하드웨어 장치마다 존재하면서 이들을 제어하는 작은 CPU라고 할 수 있다.
OS는 컴퓨터가 부팅되었을 때부터 항상 수행되면서 각종 자원들을 관리해야 하므로 항상 메모리에 올라가 있다.
하지만 OS의 모든 코드를 다 메모리에 상주시키면 메모리의 낭비가 발생하게 된다. 따라서 OS 중 항상 메모리에 올라가 있는 부분은 전체 OS 중 핵심적인 부분에 한정되며, 이 부분을 커널(kernel)
이라고 한다.
Dual Mode in OS by setting mode bit
시스템의 중요한 동작들을 OS
가 관리한다.
Why dual mode(or multi-mode)?
OS 그 자체와 다른 시스템의 구성요소들을 보호하기 위해서다.
Timer가 동작되면 기존 프로그램을 멈춘 다음, User 모드에서 Kernel 모드로 이동시킨 후 그 다음 프로그램을 수행시킨다.
User program이 CPU를 독점(monopolizing)
하는 것을 막아준다.
시분할 시스템(time-sharing system)
구현에 사용된다.
컴퓨터에서 연산을 한다는 것은 CPU가 무언가 일을 한다는 뜻이다.
각 장치마다 이를 제어하기 위해 설치된 장치 컨트롤러는 장치로부터 들어오고 나가는 데이터를 임시로 저장하기 위한 작은 메모리를 가지고 있는데, 이를 로컬버퍼(local buffer)
라고 부른다.
디스크나 키보드 등에서 데이터를 읽어오는 경우, 우선 로컬버퍼에 데이터가 임시로 저장된 후 메모리에 전달된다.
이때 장치에서 로컬버퍼로 읽어오는 일은 컨트롤러(controller)가 담당한다.
로컬버퍼로 읽어오는 작업이 끝났는지를 메인 CPU가 지속적으로 체크하는 것이 아니라 장치에 있는 컨트롤러가 인터럽트를 발생시켜 CPU에 보고하게 된다.
이때 인터럽트(interrupt)
란 컨트롤러들이 CPU의 서비스가 필요할 때 이를 통보하는 방법을 말한다.
기본적으로 CPU는 매 시점 메모리에서 명령(instruction)을 하나씩 읽어와서 수행한다.
이때 CPU 옆에는 인터럽트 라인(interrupt line)
이 있어서, CPU가 자신의 작업을 하던 중간에 인터럽트 라인에 신호가 들어오면 하던 일을 멈추고 인터럽트와 관련된 일을 먼저 처리한다.
즉, CPU는 명령 하나를 수행할 때마다 인터럽트가 발생했는지 확인한다.
OS는 각종 HW 및 SW 자원 관리뿐 아니라 사용자 프로그램에 필요한 서비스도 제공한다. 그 중 한가지가 인터럽트 처리루틴이다.
CPU는 하던 일을 잠시 멈추고 이 인터럽트가 발생하였을 때 OS 커널 내에서 해당 인터럽트의 처리를 위해 정의된 코드를 찾아 수행한다.
이때 수행하는 일은 디스크의 로컬버퍼에 있는 내용을 사용자 프로그램의 메모리로 전달하고, 해당 프로그램이 CPU를 할당받을 경우 다음 명령을 수행할 수 있음을 표시해두는 일이다.
OS는 할 일을 쉽게 찾아가기 위해 인터럽트 벡터(interrupt vector)
를 가지고 있다.
인터럽트 벡터
란 인터럽트 종류마다 번호를 정해서, 번호에 따라 처리해야 할 코드가 위치한 부분을 가리키고 있는 자료구조를 말한다.
실제 처리해야할 코드는 인터럽트 처리루틴(interrupt service routine) 또는 인터럽트 핸들러(interrupt handler) 라고 불리는 다른 곳에 정의된다.
Software interrupt 또는 Internal interrupt
Trap
의도적이다.
예시) system call
이벤트 수행하고 나면 “next” 명령으로 간다.
Fault
의도치 않는 실수이지만 복구 가능하다.
예시) page fault
“current” 명령을 재수행하거나 중단한다.
Abort
의도치 않는 실수이고 복구 불가능하다.
예시) illegal instruction
현재 프로그램이 멈춘다.
인터럽트 핸들링(interrupt handling)이란 인터럽트가 발생한 경우에 처리해야 할 일의 절차를 의미한다.
OS는 현재 시스템 내에서 실행되는 프로그램들을 관리하기 위해 프로세스 제어블록
(Process Control Block: PCB)이라는 자료구조를 둔다.
PCB는 각각의 프로그램마다 하나씩 존재하며 해당 프로그램의 어느 부분이 실행 중이었는지를 저장하고 있다.
프로그램 A가 실행되던 중에 인터럽트가 발생하면 A의 현재 상태를 PCB에 저정한 후 CPU의 제어권이 인터럽트 처리루틴으로 넘어가게 되며, 인터럽트 처리가 끝나면 저장된 상태를 PCB로부터 CPU상에 복원해 인터럽트 당하기 직전의 위치부터 실행이 이어지게 되는 것이다.
동기식 입출력은 프로그램 A가 입출력 요청을 했을 때 입출력 작업이 완료된 후에야 프로그램 A의 후속 작업을 수행할 수 있는 방식을 말한다.
동기식 입출력에서 CPU는 입출력 연산이 끝날 때까지 인터럽트를 기다리며 자원을 낭비하게 된다.
DMA(Diredt Memory Access)
원칙적으로 메모리는 CPU에 의해서만 접근할 수 있는 장치이다.
CPU 외의 장치가 메모리의 데이터에 접근하기 위해서는 CPU에게 인터런트를 발생시켜 CPU가 이를 대행하는 식으로만 가능하다.
하지만, 컨트롤러가 CPU에게 인터럽트를 발생시키면 CPU는 컨트롤러의 로컬버퍼와 메모리 사이에서 데이터를 옮기는 일을 하게 된다.
모든 메모리 접근 연산이 CPU에 의해서만 이루어질 경우 입출력 장치가 메모리 접근을 원할 때마다 인터럽트에 의해 CPU의 업무가 방해를 받게 되어 CPU 사용의 효율성이 떨어지는 문제점을 발생하게 된다.
이러한 비효율성을 극복하기 위해 CPU 이외에 메모리 접근이 가능한 장치를 DMA
라고 부른다.
DMA는 일종의 컨트롤러로서, CPU가 입출력 장치들의 메모리 접근 요청에 의해 자주 인터럽트 당하는 것을 막아주는 역할을 한다.
이때 DMA는 블록(block) 이라는 큰 단위로 정보를 메모리로 읽어온 후에 CPU에게 인터럽트를 발생시켜서 해당 작업의 완료를 알려준다.
이러한 방식으로 CPU에게 발생하는 인터럽트의 빈도를 줄여 CPU를 좀 더 효율적으로 관리하고 입출력 연산을 빠르게 수행할 수 있게 된다. (interrupt 낮추고, CPU 성능 높이는)
Northbridge(= Memory Controller Hub) : PC motherboard 에 있는 핵심 로직 칩셋에서 두개의 칩 중 하나이다.
CPU, Memory, Graphic card에 직접적으로 연결 O
매우 빠른 의사소통을 처리한다.
PCle bus를 통해 “southbridge”로 연결된다.
Southbridge(= I/O Controller Hub) : 모든 컴퓨터 I/O 기능들을 관리하는 칩이다.
USB, audio, serial, BIOS 등등
CPU에 직접적으로 연결 X
정규 표현식
은 특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어이다. -위키백과-어떤 텍스트 내에서 특정한 형태나 규칙을 가진 문자열 을 찾기 위해 그 형태나 규칙을 나타내는 패턴을 정의하는 식이다.
Matcher 클래스는 대상 문자열의 패턴을 해석하고 주어진 패턴과 일치하는지 판별할 때 주로 사용된다.
Matcher 클래스의 입력값으로는 CharSequence라는 새로운 인터페이스가 사용되는데 이를 통해 다양한 형태의 입력 데이터로부터 문자 단위의 매칭 기능을 지원 받을 수 있다.
Matcher객체는 Pattern객체의 matcher() 메소드를 호출하여 받아올 수 있다.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexExample {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("^[a-zA-Z]*$"); //영문자만
String val = "abcdef"; //대상문자열
Matcher matcher = pattern.matcher(val);
System.out.println(matcher.find());
}
}
위 예제는 Matcher 클래스의 find() 메서드를 활용하여 대상문자열이 영문자인지 검증하는 예제이다.
영문자가 맞다면 ture 그렇지 않다면 false가 출력된다.
우아한테크코스에서 왼손님과 포비님이 유튜브로 진행한 코수타에서
제 기준으로 중요한 내용 혹은 알면 좋은 내용들을 정리해봤습니다.
자세한 얘기를 듣고 싶은 분들은 아래의 링크(URL)를 통해 들어주시면 좋을 것 같습니다!
스스로 문제를 해결하자.
취업 준비생을 위한 10개월간 무료교육과정
현장지향형 교육 운영
독학으로 3~6개월간 독학한 친구들이 프리코스를 참여한다면, 합격할 수 있다고 본다.
함께 하는 교육자분들이 현장 경험이 최소 2년 이상인 게 장점이라 본다.
level 1,2는 과제 진행 → 현장 개발자들에게 1대1 코드 리뷰를 받아볼 수 있다.
강의식, 이론 기반보다는 실무+능동+주도적인 교육기관이다.
과제 기반 교육을 운영
강의는 최소한으로 할 예정
*짧은 기간 동안 코드에 대해서 읽기 좋은, 유지 보수, 리팩토링 → 경험들을 배울 것임.
함께 성장, 학습하기 위해서 만든 커뮤니티.
peer 코드 리뷰 - 서로 의견 공유
아고라 - 학습에 관련한 토론, 질의응답
학습 컨텐츠 공유 - 내가 학습을 해서 블로그나 외부 학습자료를 공유
스스로 먼저 해보는게 중요하다. (자기주도학습)
2주차 첫번째 부터 시작한다.(11월 1일)
1주차 끝난 이후에, 코치분들이 공통 피드백을 나갈거다.
다음 주차에 공통 피드백을 반영할 예정이다.