반효경 교수님의 운영체제 강의와 Operating System Concepts 10th ed. 를 참고하였습니다.
파일 시스템의 실행 파일을 실행하면, 메모리에 올라가서 프로세스가 된다.
사실은 이 사이에 한 과정을 더 거친다.
논리 주소(가상 메모리)와 물리 주소는 다른 주소이기 때문에 주소 변환이 필요하다.
code(text)
영역에는 우리가 작성한 코드가 컴파일을 거쳐 기계어 형태로 존재하고 있다.data
영역에는 전역변수나 프로그램이 시작해서 종료할 때까지 남아있는 데이터가 저장된다. heap
영역에는 런타임 동안 동적으로 할당되는 공간이다. (new로 생성한 객체 등)stack
영역에는 함수 호출과 리턴에 관련한 정보, 지역변수 등을 저장한다. code
영역data
영역stack
영역실행중인 프로그램을 말한다.
프로세스의 문맥(CPU 사용량, 메모리 사용량, 파일을 얼마나 열고 있는가 등)
CPU 수행 상태를 나타내는 하드웨어 문맥
프로세스의 주소 공간
프로세스 관련 커널 자료 구조
프로세스가 생성중일 때, new
상태라고 부른다.
프로세서가 하나이기 때문에, 매 순간 기계어를 실행하는 하나의 프로세스를 running
상태에 있다고 부른다.
CPU 사용을 위해 기다리고 있는 프로세스들을 ready
상태에 있다고 부른다.
현재 CPU를 넘겨받아도 당장 실행할 수 없는 프로세스들(I/O 작업 대기)을 blocked(wait, sleep)
상태에 있다고 부른다.
ready
로 바꾼다.프로세스의 작업이 완료되면 terminated
상태가 된다.
운영체제는 자신의 data영역에 queue를 만들어 프로세스들을 관리한다.
PCB에는 Linked list 형태의 자료구조인 queue로 프로세스를 관리하기 위해 pointer
변수를 가지고 있다.
그 외에 프로세스의 우선순위, Process ID, 스케줄링 정보 등을 가지고 있다.
실제로 Program counter와 register는 CPU가 이미 가지고 있는 값이다. 그런데 PCB는 왜 프로세스마다 이런 정보를 가지고 있을까?
우리가 사용하는 OS는 시분할 시스템이기 때문에, CPU 사용권을 프로세스마다 일정 시간 간격마다 나누어 사용하게 된다. 만일, 프로세스가 실행 중에 다른 프로세스에게 넘어가면 현재 Program counter, register값은 새 프로세스에 의해 대체될 것이다. 그렇기 때문에 다른 프로세스에게 CPU를 넘겨줬다가 다시 프로세스를 이어서 실행하려면 그 프로세스가 실행중이던 문맥(context)이 필요하다. 그 중에서, 현재 레지스터에 담고 있던 값, 실행하던 메모리 주소는 필수적일 것이다. 그렇기 때문에 운영체제가 프로세스 별로 해당 정보를 백업해두고 관리하는 것이다.
Job queue
: 현재 시스템 내에 있는 모든 프로세스의 집합Ready queue
: 현재 메모리 내에 있으면서 CPU를 받으면 즉시 실행 가능한 프로세스의 집합
Device queues
: I/O device의 처리를 기다리는 프로세스의 집합
degree of Multiprogramming
을 제어한다.time-sharing systems such as UNIX and Microsoft Windows systems often have no long-term scheduler but simply put every new process in memory for the short-term scheduler.
Because of the short time between executions, the short-term scheduler must be fast. If it takes 10 milliseconds to decide to execute a process for 100 milliseconds, then 10/(100+10) = 9 percent of the CPU is being wasted simply for scheduling the work.
Suspended
상태가 된다. Running
상태에는 두 가지 모드가 있다.Suspended
에도 두 가지 종류가 있다.Blocked
상태에서 swap되는 경우 Ready
상태에서 swap되는 경우Suspended
상태에서는 메모리를 빼앗기지만, I/O 작업의 완료 등은 처리할 수 있다.A thread is basic unit of CPU utilization
스레드는 프로그램의 실행 단위이다. 각 스레드는 독자적인 ID, program counter, register set, stack을 가진다. 우리가 배운 프로세스들은 스레드가 하나인 프로세스라고 볼 수 있다. (traditional/heavyweight process)
동일한 코드를 수행하는 프로그램에서 동시에 다른 작업을 할 때, 프로세스로 작업을 관리한다면 Code, data 등의 중복된 내용의 메모리 영역이 낭비된다. 그런 경우 스레드를 여러 개 만드는 것이 효과적일 수 있다. 단일 프로세스의 주소공간 내에서 code와 data, heap 영역을 공유하며 실행될 수 있기 때문이다.
Responsiveness
: 다중 스레드로 구성된 태스크 구조에서는 하나의 서버 스레드가 blocked (waiting) 상태인 동안에도 동일한 태스크 내의 다른 스레드가 실행되어 빠른 처리를 할 수 있다.A web browser might have one thread display images or text while another thread retrieves data from the network, for example.
Resource Sharing
: 프로세스 간에 자원을 공유하려면, sheard memory나 message passing과 같은 처리를 개발자가 해주어야 한다. 하지만, 스레드는 기본적으로 code와 data 영역을 공유한다.
Economy
: 프로세스를 만들고 context switch하는 것보다 스레드를 만드는 것이 훨씬 cost가 적다.
Scalability
: MultiProcessor 환경에서 스레드가 병렬적으로 처리될 수 있다. 멀티코어를 잘 활용할 수 있다.
Concurrency vs Parallelism
Concurrency(동시성)
Parallelism(병렬성)
Kernel Threads
User Threads
커널 스레드는 하나이고, 유저가 내부적으로 스레드를 만들어 멀티 스레드로 동작하게 만든 경우
유저 스레드 하나 당 커널 스레드를 배치하는 방법
유저 스레드보다 같거나 적은 커널 스레드를 가지는 모델이다. 위 두 모델의 단점을 극복한 모델이라고 볼 수 있다. Many-to-One의 단점인 멀티코어에서의 동시성 문제와, One-to-One의 단점인 커널 스레드 생성 비용을 절충한다.
유저 스레드는 마음껏 만들고, 멀티코어에서 병렬적으로 동작 가능한 수준으로 커널 스레드를 만들어준다.
exit()
시스템 콜을 통해 종료한다는 사실을 운영체제에게 알린다.