목차
4주차 범위
Chapter 09: 운영체제 시작하기
Chapter 10: 프로세스와 스레드
Chapter 11: CPU 스케줄링
이번주차부터 운영체제네요
CPU 스케줄링 저거 어려웠던거 같은데 최대한 꼼꼼히 봐야겠네요
학습 내용 정리
Chapter 09: 운영체제 시작하기
운영체제 : 사용자와 하드웨어 사이에 인터페이스 역할을 하는 소프트웨어
운영체제는 하드웨어와 응용프로그램 사이에 동작하며 자원을 관리
커널 영역과 사용자 영역
메모리 내 공간은 커널 영역과 사용자 영역으로 나뉨
- 커널 영역: 운영체제가 적재되는 영역
- 사용자 영역: 프로그램이 동작하기 위해 사용되는 메모리공간으로 스택영역, 힙 영역, 데이터 영역, 코드 영역으로 이루어짐
사용자 인터페이스 (UI): 운영체제가 제공하는 서비스 중 하나(커널에는 포함안됨)
UI 의 종류
- CLI(Command Line Interface): 입출력이 텍스트로 이루어지는 인터페이스 (cmd, dos 등)
- GUI(Graphic User Interface): 그래픽 환경의 인터페이스
- NUI(Natural User Interface) : 자연스러운 움직임을 통해 기기를 조작하는 인터페이스
이중 모드: 운영체제가 응용 프로그램이 자원에 접근하는 과정을 요청받으면 대신 수행
커널 모드: 커널 영역 코드 실행 가능
사용자 모드: 커널 영역 코드 실행 불가
커널 모드에서는 자원에 접근이 가능하다
시스템 콜: 프로그램이 자원에 접근 하기 위해서는 운영 체제에 요청을 보냄
시스템 콜을 통해 커널 모드로 전환되면 운영체제 서비스를 제공 받을 수 있음
시스템 호출은 소프트웨어 인터럽트임
시스템 콜 작동 과정
(사용자모드)시스템 호출을 발생 시킴 -> (커널모드)운영체제 코드 실행 -> (사용자모드) 시스템 호출 복귀
운영 체제의 핵심 서비스
- 프로세스 관리
- 자원접근 및 할당
- 파일 시스템 관리
CPU 스케줄링: 하나의 CPU는 한번에 하나의 프로세스만 할당 가능하므로 어떤 프로세스 부터, 얼마나 오래 할당할지 스케줄링 필요
가상머신: 소프트웨어적으로 만들어낸 가상컴퓨터
하이퍼바이저 모드: 가상머신을 위한 모드
가상 머신은 대표적으로 VMWare, Virtual Box 등이 있습니다.
Chapter 10: 프로세스와 스레드
프로세스: 메모리에 적재되어 실행되고있는 프로그램
포그라운드 프로세스: 사용자가 상호작용 할수 있으며 보이게 실행되고 있는 프로세스
백그라운드 프로세스: 보이지 않게 실행되고 있는 프로세스
사용자와 상호작용하지 않는 백그라운드 프로세스는 유닉스 계열에서는 데몬, 윈도우 계열에서는 서비스라고 지칭
PCB(프로세스제어 블록): 프로세스 관련 정보를 저장 하는 자료구조
PCB 에 담기는 정보
- PID: 프로세스ID - 프로세스 식별번호
- 레지스터 값
- 프로세스 상태 정보
프로세스의 메모리 영역
- 코드영역
- 데이터 영역: 프로그램이 실행되는 동안 유지되는 데이터가 저장
- 힙 영역: 프로그래머가 직접 할당할수있는 메모리 공간으로 후에 반환해야함
- 스택 영역: 데이터를 일시 저장
변수의 종류 별 저장 영역
전역 변수: 데이터 영역
매개변수, 지역 변수: 스택 영역
정적 할당 영역과 동적 할당 영역
정적 할당 영역: 데이터 영역
동적 할당 영역: 스택 영역, 힙 영역
프로세스상태 다이어그램
1: 생성 / 2: 준비 / 3: 실행/ 4: 완료/ 5: 대기
디스패치: 프로세스가 준비상태에서 실행 상태로 전환
프로세스 계층 구조
부모 프로세스, 자식프로세스
자식 프로세스는 부모 프로세스로 부터 생성된 프로세스다.
부모 프로세스가 종료되면 자식 프로세스도 종료된다.
스레드: 프로세스를 구성하는 실행의 흐름 단위
단일 스레드 프로세스: 스레드를 하나 가지는 프로세스
멀티프로세스: 프로세스가 여러개 실행 됨
멀티스레드: 스레드를 여러 개 가지는 프로세스
스레드 끼리는 프로세스 내의 자원을 공유한다.
프로세스 간은 기본적으로 자원을 공유 하지 않음
IPC: 프로세스 간 데이터를 주고받음.
Chapter 11: CPU 스케줄링
CPU 스케줄링: 프로세스들에게 합리적으로 CPU자원을 배분
프로세스 우선순위
CPU 버스트: 프로세스가 실행 되는 동안 CPU에서 연산을 처리 하는 시간
입출력 버스트: 프로세스가 실행 되는 동안 I/O 장치에서 작업을 하는 시간
스케줄링 큐: CPU 할당을 위해 프로세스를 대기시키고 이를 스케줄링 큐로 관리한다.
준비 큐: CPU 를 이용햐야하는 프로세스들이 대기
대기 큐: I/O 장치를 이용해야 하는 프로세스들이 대기
스케줄링 기법
종류 | 설명 |
선입 선처리 스케줄링 | 준비 큐에 삽입된 순서 대로 할당 |
최단 작업 우선 스케줄링 | CPU 사용 시간이 짧은 순으로 할당 |
라운드 로빈 스케줄링 | 정해진 시간만큼 돌아가며 CPU 할당 |
우선순위 스케줄링 | 가장 높은 우선순위 프로세스에 CPU 할당 |
다단계 피드백 큐 스케줄링 | 프로세스들이 큐 사이를 이동 할 수 있는 다단계 큐 스케줄링 |
과제
p,304 확인 문제 1번
프로세스 상태 구조도를 보고 빈칸에 알맞은 상태를 쓰시오
풀이
1: 시작하는 부분이므로 생성
2: 프로세스는 생성에서 준비 상태로 진입
3. 준비에서 실행 상태로 진입(디스패치)
4. 실행 후에 완료상태로 진입
5. 입출력 요청이 있으면 준비 상태로 진입, 완료 후에는 다시 준비 상태로 진입
정답
1: 생성
2. 준비
3: 실행
4. 완료
5. 대기
11-2 CPU 할당 순서
준비 큐에 A,B,C,D 순으로 삽입 되었을때 선입 선처리 알고리즘 적용 시 어떤 순서로 CPU를 할당받는가?
풍이
선입 선처리의 경우 무조건 먼저 삽입된 프로세스 부터 CPU를 할당한다.
따라서 A, B, C, D 순으로 프로세스를 할당 받는다
답: A, B, C, D
추가 학습
https://github.com/kangtegong/self-learning-cs/blob/main/process/process_cplusplus.md
self-learning-cs/process/process_cplusplus.md at main · kangtegong/self-learning-cs
『혼자 공부하는 컴퓨터구조 & 운영체제』 (한빛미디어). Contribute to kangtegong/self-learning-cs development by creating an account on GitHub.
github.com
예제 코드도 한번 확인해봅시다.
전 파이썬을 모르는 관계로 c++ 만 봤습니다.
1. 프로세스를 생성하고 PID 를 확인
참고로 예제코드에서는 unistd.h 사용하고 있는데 이건 리눅스환경에서 사용하는 헤더라고 합니다.
저처럼 윈도우 환경이신 분들은 다른방법을 사용해야 합니다
#include <iostream>
#include <string>
#include <cstring>
#include<stdio.h>
#include <io.h>
#include <sys/types.h>
#include <Windows.h>
using namespace std;
int main()
{
cout << "hello, os\n";
// pid 확인
cout << "pid: " << GetCurrentProcessId() << endl;
}
2. 자식 프로세스 생성, pid 확인
#include <iostream>
#include <string>
#include <cstring>
#include<stdio.h>
#include <io.h>
#include <sys/types.h>
#include <Windows.h>
#include <strsafe.h>
using namespace std;
int main()
{
cout << "hello, os\n";
// pid 확인
cout << "parent pid is " << GetCurrentProcessId() << "\n";
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
TCHAR exePath[MAX_PATH];
// 자식 프로세스로 실행할 프로그램 경로
StringCchCopy(exePath, MAX_PATH, TEXT("C:\\Windows\\System32\\notepad.exe"));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
static bool IsChildProcess = false;
if (!IsChildProcess)
{
// 프로세스생성.
IsChildProcess = true;
if (!CreateProcess(NULL, exePath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
printf("CreateProcess failed (%d)\n", GetLastError());
return 0;
}
cout << "child pid is " << pi.dwProcessId;
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
return 0;
}
예제코드랑은 동작이 다르다.
fork() 는 프로세스를 복제 하는데 createprocess 는 경로에 해당되는 프로세스를 실행 하는 식으로 자식 프로세스를 생성하므로
예제처럼 동일한 프로그램을 자식 프로세스로 생성 할 수가 없어서 부득이하게 notepad.exe 를 자식 프로세스로 실행 하도록 했다.
정확히는 자기 자신의 경로를 CreateProcess 에 넣어서 실행하면 자식프로세스가 무한히 생기게 된다.
한번만 실행시키려면 외부 txt 파일이나 ini 파일같은데 플래그 저장해서 쓰면 되긴 하겠지만 복잡하므로 그냥 다른프로그램을 실행시켰습니다.
이후 실습은 CreateProcess()로는 직접 비슷하게 진행하긴 힘들어서 간단하게 확인만 하겠습니다.
동일한 작업을 하는 프로세스 만들기
01 #include <stdio.h>
02 #include <unistd.h>
03
04 void foo() {
05 printf("execute foo\n");
06 }
07
08 int main()
09 {
10 if (fork() == 0) {
11 if (fork() == 0) {
12 // 11줄에서 fork된 또 다른 child 프로세스
13 printf("child of child pid is %d\n", getpid());
14 foo();
15 }
16 else {
17 // 10줄에서 fork된 child 프로세스
18 printf("child pid is %d\n", getpid());
19 foo();
20 }
21 }
22 else {
23 if(fork() == 0) {
24 // 23줄에서 fork된 child 프로세스
25 printf("child pid is %d\n", getpid());
26 foo();
27 }
28 else {
29 // parent 프로세스
30 printf("parent pid is %d\n", getpid());
31 foo();
32 }
33 }
34
35 return 0;
36 }
부모 프로세스는 다른 자식 프로세스를 생성할 수 있고,
자식 프로세스도 자식 프로세스를 생성할 수 있습니다.
'혼공- 컴퓨터구조, 운영체제' 카테고리의 다른 글
[혼공컴운]6주차_가상 메모리/ 파일 시스템 (4) | 2025.02.21 |
---|---|
[혼공컴운]5주차_프로세스 동기화/ 교착 상태 (0) | 2025.02.14 |
[혼공컴운] 3주차_메모라와 캐시메모리/ 보조기억장치/ 입출력장치 (0) | 2025.01.21 |
[혼공컴운] 2주차_CPU의 작동원리/ CPU 성능 향상 기법 (1) | 2025.01.15 |
[혼공컴운] 1주차_컴퓨터 구조 시작하기/ 데이터/ 명령어 (1) | 2025.01.02 |