기록을 남기자

전체 글 186

카테고리 설명
개발,CS,PS 기록을 남기려 합니다.
  • Relationship Between Threads and Processes 이 중, 주목해봐야할 관계는 Threads : Processes = 1 : M 스레드가 1개인데 프로세스가 여러개인 형태이다. 위의 시스템은 프로세스가 여러개인데, 스레드가 1개이다. P1, P2, P3가 같은 컴퓨터 시스템 안에 있는 경우라면 이런 방식은 말이 안된다. P1, P2, P3를 네트워크로 연결된 서로 다른 컴퓨터에서 각각의 프로세스를 관리하고 있고, 스레드는 P1에서 실행하다가 P2로 옮겨가고 P3로 옮겨가는 방식이다. 1 : N + M : 1 = N : M Windows Process and Thread Windows의 스레드 관리 방법 Multi-Threading System 을 거의 그대로 따르는, 기본이 되..

  • fork() Parent Process가 Child Process를 만들라는 명령어 → Child Process는 Parent Process의 모든 코드를 copy해간다. int main(){ int i; fork(); for(i=0;i Thread 생성 시간 프로세스 생성 → 모든 것을 copy 해야한다. 프로 독립된 구조체이다. 즉, 프로세스는 복사하게 되면 많은 양의 정보들을 복사해야하기 때문에 생성시간이 길어진다. ⇒ 생성시간도 길어지게 되고, 없앨 때도 메모리, 자원, 스위칭 시간 등등을 할당된 자원을 다시 반납해야 하기 때문에 소요시간이 길어지게 된다. ↔ 하지만, Thread는 프로그램 코드와 데이터를 Share 를 할 수 있기 때문에 모든 것을 copy할 필요가 없다. ⇒ 생성시간이 줄어들..

  • 기초 쿼리 문법 1. 작성 순서 SELECT - FROM - WHERE - GROUP BY - HAVING - ORDER BY SELECT (컬럼명) FROM (테이블명) GROUP BY(항상 WHERE 뒤) : 그룹화하여 단일 값으로 축소함 HAVING(항상 GROUP BY 뒤) : 그룹화 조건 확인 (count등이 쓰임) 2. 많이 쓰이는 함수 모음 DATE_FORMAT(시간값, 원하는 포맷) : 날짜형식 지정 Y : 2022, y : 22 M: september, m:09, a: Sep d:23(일자) T : hh:mm:ss 예시 SELECT DR_NAME, DR_ID, MCDP_CD, DATE_FORMAT(HIRE_YMD, "%Y-%m-%d") AS HIRE_YMD FROM DOCTOR WHERE..

  • OS의 실행방식 세가지 1. Non-process kernel OS Kernel을 별개의 객체로 보는 방식이다. 각 Process 관리 방식 != OS kernel 관리 방식 OS는 특별한 권한을 가지고 있다. OS는 별개의 entity로 시스템 안에서 실행되는 객체이다. OS가 작아서 OS전체가 Memory에 올라갈 수 있던 옛날에 가능했던 방식이다. OS가 작아서 전체가 Memory에 올라가, Virtual Memory를 사용할 필요가 없다. 2. Execution Within User Processes OS를 User Process 안에서 실행시키는 방식이다. OS에서 굉장히 중요한 부분 빼고, 나머지 부분들을 Process 안에서 실행 시킨다. P1 ~ Pn까지 User Process안에 OS f..

  • OS 또한 Program이기에 Memory의 공간을 차지한다. tree가 pointer와 연결되어 있다. Primary Processiable 또한 OS에서 관리한다. Swapping Area에는 하드디스크일지라도 File Area에 들어 있는 실행 파일과 다르게 Code + Data + PCB + Stack이 모두 포함된 Process 상태로 저장되어 있다. Process Description OS가 Process를 어떻게 관리하는지가 중요하다. Operating System Control Structure 1. 각각의 Process와 여러가지 Resource의 Current Status에 대한 정보를 관리한다. 2. OS는 System 내부 자원 관리를 위해 다음의 네가지 테이블을 만들어서 관리한다...

작성일
2023. 4. 4. 12:36
작성자
ssun_bear
반응형

Relationship Between Threads and Processes

이 중, 주목해봐야할 관계는
Threads : Processes = 1 : M

스레드가 1개인데 프로세스가 여러개인 형태이다.

위의 시스템은 프로세스가 여러개인데, 스레드가 1개이다.
P1, P2, P3가 같은 컴퓨터 시스템 안에 있는 경우라면 이런 방식은 말이 안된다.
P1, P2, P3를 네트워크로 연결된 서로 다른 컴퓨터에서 각각의 프로세스를 관리하고 있고, 스레드는 P1에서 실행하다가 P2로 옮겨가고 P3로 옮겨가는 방식이다.

1 : N + M : 1 = N : M


Windows Process and Thread

Windows의 스레드 관리 방법
Multi-Threading System 을 거의 그대로 따르는, 기본이 되는 시스템이다.

각각의 OS별로 스레드 관리 방법이 어떻게 다른지 알아야 한다.

  1. 객체(Object)로 구현된다.
  2. Windows는 새로운 Process가 만들어지기도, 기존의 Process가 복사본으로 만들어지기도 한다.
    → 둘 다 가능하다.
    Unix는 반드시 기존의 부모 프로세스를 복제하여 자식 프로세스를 생성해야 한다.
    ⇒ 새로운 프로세스로 만들어질 수 없다.
  3. 실행가능한 프로세스는 반드시 최소 하나 이상의 스레드를 가지고 있어야 한다.
    스레드가 다른 스레드들을 만들며 스레드의 수가 변한다.
  4. 스레드는 dispatchable 한 작업의 단위이다.
    → 실행단위가 스레드이기 때문에 Dispatch도 스레드 단위로 한다.
    dispatchable : ready queue에 스레드가 줄 서 있다는 의미
    → Process와 thread 둘 다 동기화 툴들을 가지고 있다.

Windows Process Object Attributes

Process의 Attribute들

프로세스는 자원 관리 단위 이다.

Execution time

프로세스가 실행하는 게 아니다.
실제 실행은 프로세스 내부에 속해있는 스레드들이 한다.

⇒ Process 내부의 스레드들이 CPU가 얼마나 사용했는지를 적어 놓은 것이다.

I/O counters

⇒ Process 내부에 있는 스레드들이 어떤 I/O 작업을 몇 번이나 했는지를 적어 놓은 것이다.

VM operation counters

⇒ Process 내부에 있는 스레드들이 Virtual Memory 관련된 작업들을 몇번이나 했는지? 를 적어 놓은 것이다.

실제로 실행을 시키는 것이 아니라, 이 프로세스 안에서 실행을 하고 있는 스레드들이 실행을 하면서 자원을 얼만큼 사용했는지 하는 것들을 적어 놓은 부분이다.

Base Priority

스케쥴링 우선순위 : Ready Queue에서 스레드들이 줄을 서 있을 때, CPU를 먼저 차지하는 순위

Q.thread가 실행 단위이므로 thread가 우선순위를 가져야 하는데, Process는 실행도 안하는게 왜 우선 순위를 갖는가?

→ Base Priority 는 해당 프로세스에 속한 스레드들의 우선순위 minimun 값이다.

Default Processor affinity
교수님이 제일 재밌다고 한 기능

내가 좋아하는 CPU라는 뜻이다.
→ 시스템 안에 CPU가 하나만 있는 경우는 의미가 없고, CPU가 여러개 있는 프로세스가 있다고 할 때,
이 프로세스가 좋아하는 CPU는 1번, 3번, 5번 이라고 할 때,
이 프로세스에 속한 스레드들은 1번, 3, 5번에서 가능하다면 실행을 시키라는 의미이다.

Q. 왜 이 기능이 스레드 단위가 아니라 프로세스 단위로 존재할까?

→ 이 경우는 프로세스 단위로 관리되는 것이 맞다.
스레드 단위로 관리되는 정보가 아니다.
왜냐하면, Default Processor affinity 이 정보와 연관된 것은 Cache이다.

프로그램 → 스레드가 여러개 → 스레드 한 개를 CPU1에서 실행
                     ↳ 이 프로그램의 code, data가 CPU1의 cache에 존재한다는 의미
                     → 이 프로세스의 다른 스레드를 CPU3에서 실행 
                     ↳ 다시 이 프로그램의 code, data를 CPU3의 cache로 Copy 해야한다.

⇒ 위의 상황의 경우, 계속 code, data(공유 데이터) Copy 해야하는 상황이 반복된다.

↔ 그게 아니라, 내가 이 프로세스의 다른 스레드를 CPU1에서 실행시키면, CPU1에 내 code, data가 이미 존재할 것이다.
⇒ 그럼 다시 caching 할 필요가 없다.

이 프로세스가 실행은 스레드 단위로 하지만,
실행한다는 말은 코드와 데이터를 읽는다는 뜻이므로
몇 번 CPU Cache 안에 내 code와 data가 있느냐에 따라서 가급적이면 그 CPU에서 다시 copy하지 않고 내 스레드가 실행 됐으면 좋겠다 라고 하는 것이 Default Processor affinity 정보들이다.


Windows Thread Object Attributes

Thread 는 실행의 단위이다.

Thread Context

가장 중요한 스레드 속성이다.
스레드는 실행의 단위인데, 이 스레드가 실행이 됐다가 중단이 됐다가 하면서 중단된 지점의 CPU의 상태 를 저장하는 Thread Context 를 가지고 있다.

Dynamic Priority

스레드의 진짜 우선순위를 의미한다.
→ 스레드 별로 다 다르다.

Base Priority

스레드가 속한 프로세스에게 상속 받은 우선순위로 스레드의 minimum priority 이다.


Windows Thread States

Suspend 상태는 Process 단위의 상태인데,
스레드의 상태일 수도 있다.
⇒ Thread의 Suspend Vs. Process의 Suspend 를 구분할 줄 알아야 한다.

두 개의 Suspend를 갖는 프로세스 상태는 4장에서는 더 이상 사용하지 않는다.
→ 프로세스 상태와 스레드 상태를 구분해야하기 때문이다.

Runnable 상태

Ready → Standby → Running

  1. Ready 상태
    실행할 수 있는 상태
  2. Running 상태
    실행하고 있는 상태
  3. Standby 상태
    Ready Queue에 있는 스레드들 중에서 다음에 실행할 스레드를 하나 골라서 얘를 Standby 상태로 둔다.
    그리고 나서 원래 Running 하고 있던 프로세스 스레드가 종료되면 상태를 바꾼다.

Running → Ready

두 가지 이유가 존재한다.

1. Timeout

CPU를 뺏긴다.

2. Priority

우선순위가 더 높은 스레드의 등장으로 인하여 실행 순서에서 밀려나 CPU를 뺏겨,
Ready 상태로 가게 되는 것

Preempted : CPU를 뺏긴다는 의미

Not Runnable

Running → Terminated

Running을 하고 있다가 종료하면 Terminated 상태가 된다.

Running → Waiting

Running을 하고 있다가 I/O 요청을 해서 Block이 된다.
Running을 하고 있다가 동기화이든지, User Request 이든지, 아니면 다른 여러가지 이유로 Thread가 Suspend가 될 수 있다.

Suspension이 발생하는 여러가지 이유 중,
Process 단위에서 발생하는 Swapping을 제외하면, 나머지 형태들은 실행하고 있던 Thread 한테 발생할 수 있는 Suspension 이다.

Windows에서는 Block 상태나 Thread의 Suspend 상태나 구분하지 않고 둘 다 Waiting 상태로 보낸다.

그런데, Waiting 상태라고 하지만, Queue 가 하나가 아니다.
3장에서도 Block 이 발생할 때도 왜 Block이 발생했느냐에 따라 Queue가 다 달랐다.
I/O 작업 → 키보드 입출력, 파일 입출력, .. 각각 다른 큐에 들어가 있다.
당연히 여기도 Block 상태나 Thread의 Suspend 상태 둘 다 Waiting 상태로 표현했지만, 얘네들은 다 다른 Queue에 들어가 있다.
→ Suspend가 발생한 이유에 따라서, Block이 발생한 이유에 따라서

🌟 Block이든 Suspend이든 실행 불가능하다.
그래서 스레드가 지금 당장 실행할 수 없다라는 의미에서 두 상태가 같은 상태에 있는 것을 문제없이 볼 수 있다.

Waiting → Ready

Unblcok/Resume Resource Available

Resume : 기다리고 있던 I/O 작업 종료했거나, 동기화 문제 해결이 되어 내가 실행할 차례가 다시 된 것
⇒ Suspend 가 되었다가 다시 실행상태가 된 것
↳ 코드가 없다.

Resource Available : Resource Available일 경우 Ready로 간다.

Waiting → Trasition

Unblcok Resource Not Available
Resource Not Available : Resource Not Available일 경우 Trasition 상태로 간다.

Trasition 상태에 있는 스레드는 이 스레드를 포함하는 프로세스가 하드디스크에 존재하므로, 한참 기다리다보면 메모리가 넉넉해져서 해당하는 프로세스를 다시 메모리로 가지고 오게 된다.
이렇게 되면 resource가 available 하게 되고, 해당하는 스레드는 Ready 상태로 다시 이동하게 된다.

Q. Waiting → Ready Vs. Waiting → Trasition 차이?

Resource ?
스레드가 suspend나 blcok으로 waiting에 있는데,
이 스레드를 포함하는 프로세스가 스레드를 3개 가지고 있었는데,
이 프로세스가 가진 스레드들이 모두 Block이나 Suspend되어 Waiting 상태에 가있게 되면 더 이상 실행할 스레드가 없게 된다.
이럴 때, MidTerm Scheduler 가 이 프로세스는 실행할 스레드가 하나도 없으니까 Swapping Area 로 옮겨야 되겠다 결정을 하게 된다.
⇒ 스레드들은 Block이나 Suspend된 채로 프로세스에 담겨 Swapping Area로 이동하게 된다.
⇒ Process 상태가 Swap out 되어서, 프로세스가 Suspend 상태 가 되게 된다.

이 상황에서 Waiting 상태에 있던 프로세스에 I/O 작업이나 동기화 작업이 끝 났는데 프로세스가 Swapping Area에 있어서 코드가 존재하지 않게 된다.
이 스레드는 메모리에 올라와 있지 않은 상태이다.
이럴 때 Resource Not Available 하다고 한다.

그렇지 않고, 해당하는 스레드를 포함하는 프로세스가 계속 메모리에 잘 있으면,
즉, 스레드가 한 두개 suspend나 block이 되어 있지만 나머지 스레드들이 계속 실행을 하고 있는 경우 ,
또는 OS가 메모리가 넉넉하다고 판단해 굳이 Swap out 하지 않은 경우 Resource Available 상태라고 한다.

즉, Resource Available 과 Resource Not Available 상태의 차이는,
해당하는 스레드를 포함하는 프로세스가 메모리에 있는지 아니면 Swapping Area(하드디스크)에 존재하는지?
→ 좀 더 정확히, 프로그램 데이터와 코드가 리소스이므로 이 프로그램 데이터와 코드를 사용할 수 있는지? (메모리에 있으면 사용 가능, 하드디스크에 있으면 사용 불가능)

Trasition → Ready

Unblcok Resource Not Available

Trasition 상태에 있는 스레드는 이 스레드를 포함하는 프로세스가 하드디스크에 존재하므로, 한참 기다리다보면 메모리가 넉넉해져서 해당하는 프로세스를 다시 메모리로 가지고 오게 된다.
이렇게 되면 resource가 available 하게 되고, 해당하는 스레드는 Ready 상태로 다시 이동하게 된다.

Windows에서는 프로세스의 suspension 과 스레드의 suspension 을 따로 분리 해서 관리한다.
스레드들은 suspend가 됐을 때, blocked된 스레드와 같이 waiting 상태에 포함이 된다.
그런데, 프로세스 상태와 스레드 상태가 따로 관리가 되다 보니,
스레드가 waiting 상태에서 깨어났을 때,
해당하는 스레드를 포함하는 프로세스가 메모리에 있을수도 있고 없을 수도 있는 상황이 일어날 수 있다.
⇒ 그것 때문에 Transition 이라고 하는 상태가 존재하는 것이다.


Sloaris Processes and Threads

Window System은 Kernel Level에서 Multi-Threading을 지원하지만,
Sloaris System은 Combined된 Approach 를 사용한다.
⇒ Sloaris에서는 User Level 에서 Multi-Threading 을 지원하는 User Level Library를 가지고 있고, Kernel 에서도 당연히 Multi-Threading 을 지원한다.

위의 그림을 보면 두 개의 user thread 를 포함하는 Process가 있다.
→ 이 프로그램이 User Thread 두 개로 만들어졌는데,
이 두 개의 User Thread 를 관리하는 것은 application-level thread-library 이다.

⇒ User Thread는 Kernel에서 안보이게 된다.
그런데, 얘네들이 실행을 하려고 Kernel Level 에 Thread 를 Create 한다라고 하는 명령을 사용하게 되면,
Kernel에서는 새롭게 스레드를 하나 만드는데,
스레드라고 부르지 않고, Kernel Level Thread 를 Light Weight Process 라고 부른다.

Kernel Level Thread → Light Weight Process

Light Weight Process 로 User 가 만든 User Thread들을 실행 한다.

그림을 보면, user thread가 하나의 Light Weight Process에 매핑이 되어서, 실행이 되고 있는 상황인 것을 확인할 수 있다.

쉽게 생각하면, 다음 그림과 같다.

하나의 프로세스 안에 있는 커널에서 관리되는 프로세스는,
하나의 프로세스 안에 Light Weight Process 가 세 개 있는 모양으로 관리된다.

Sloaris 는 Combined된 Approach라 User-Level Thread가 있고,
Kernel-Level Thread가 있는데,
Kernel-Level Thread를 Kernel-Level Thread라고 안부르고
Light Weight Process 라고 부른다.

근데, 그림을 보면 Light Weight Process 에 Kernel Thread가 연결된 것이 보인다.
→ 사실 Solaris에서는 커널 스레드가 굉장히 많다.
이 중 일부는 Light Weight Process랑 매핑이 돼서 Light Weight Process를 실행시킨다. 이때는 Light Weight Process 가 Kernel Thread라고 봐도 무방하다.

문제는, Light Weight Process랑 매핑되지 않은 커널 스레드들이 존재한다는 것이다.
OS 작업을 하는 스레드들은 User Program의 Light Weight Process랑 매핑되지 않은 커널 스레드인채로 작업을 한다.

정리

Sloaris 는 Combined된 Approach이고,
User-Level Thread가 있고, User-Level Thread는 User-Level에서 Thread-Library에서 관리가 된다.
실제로 시스템에서는 만약, 세개의 User-Level Thread를 3개의 Kernel-Level Thread랑 매핑시켜서 실행을 하겠다라고 한다면,
세개의 Light Weight Process로 관리가 된다.

즉, 프로세스 이미지 안에는 Light Weight Process가 세 개 있는 것이다.
Light Weight Process가 실행을 할 때, 시스템 안에 있는 커널 스레드랑 매핑이 돼서 실행이 된다.

중요한 것은 Light Weight Process랑 매핑되지 않은 커널 스레드들이 존재한다.


Solaris Thread States

상태들의 이름을 희안하게 붙여 놨다.

  1. RUN 상태 = READY 상태
  2. ONPROC (OnProcessor) 상태 = RUNNING 상태
  3. SLEEP 상태 = BLOCKED 상태
  4. STOP 상태 = SUSPEND 상태

IDLE

IDLE 상태
IDLE 상태는 어떤 누구 하고도 매핑되지 않은 스레드의 상태이다.
실행을 시작하기 전의 상태이다.

IDLE → RUN

Ligth Weight Process 와 매핑이 되면,
얘가 READY 상태가 된다.

RUN → ONPROC

READY 상태에 있다가 Switching이 되면, Running 상태가 된다.

ONPROC → RUN

Running 상태로 있다가 다시 Ready 상태가 되는 이유가 두가지 존재한다.

  1. Timeout
  2. 우선 순위가 더 높은 스레드의 등장

위의 두가지 이유로 인하여 Running 상태에 있던 스레드가 CPU를 빼앗겨 Ready 상태가 된다.

ONPROC → SLEEP → RUN

실행을 하다가 I/O 요청과 같은 System call을 요청하면, Blocked 상태가 된다.

Blocked 상태에 있는 스레드는 Blocked Queue 에 들어가 있다가,
한참 지나서 I/O 작업이 완료되면, 다시 Ready 상태로 돌아가게 된다.

ONPROC → STOP → RUN

한참 실행을 하다가, 동기화라든지, User Request 라든지, 여러 다른 이유로 Suspend가 되면, STOP 상태로 가게 된다.

STOP 상태에 있던 스레드는 Suspension의 이유가 되었던 문제가 다 해결이 되면, 다시 READY 상태로 돌아오게 된다.

Windows와 Solaris의 다른점

Windows

Blocked인 경우, Suspend인 경우 다 Waiting이라고 하는 하나의 상태로 간주

Solaris

Blocked인 상태와 Suspend 상태를 별개의 형태로 관리한다.

→ 스레드의 상태와 프로세스의 상태는 둘 다 별개로 관리한다.

ONPROC → ZOMBIE → FREE

Running을 하고 있다가 스레드를 종료하게 되면,
ZOMBIE 상태로 가게 된다.

ZOMBIE

ZOMBIE 상태는 스레드는 종료했지만, 이 스레드를 만든 스레드 즉, 부모 스레드에게 전달될 정보가 남아있는 상태이다.
⇒ 그래서 스레드를 완전히 없애지 못하고 최소한의 정보들만 남겨 놓은 상태이다.

그러다가 정보들이 다 전달이 되고 나면, FREE 상태가 되게 된다.

PINNED

PINNED 상태
Running 을 하고 있다가 인터럽트 가 발생한다.
인터럽트가 발생하면, 인터럽트 처리를 하기 위해서 OS 코드 가 실행되게 된다.
근데 Light Weight Process 랑 매핑되지 않는 Kernel Thread 들을 가지고 있는데, 그 Kernel Thread 들이 시스템 작업 을 한다.

⇒ 즉, 스레드가 실행하다가 중단이 되면, 이 스레드를 READY Queue 로 보내는 것이 아니라,
PINNED 상태로 실행을 하고 있던 CPU에 꽂아 놓는다.

꽂아 놓은채, 스레드(OS 작업을 하는 커널 스레드)가 나타나서 필요한 인터럽트 처리를 한다.

이런 인터럽트 처리를 다하고 종료시키려면, 종료시키지만,
그렇지 않은 경우에는 해당하는 스레드를 다시 실행시킨다.
⇒ 인터럽트가 발생하면 PINNED 상태로 갔다가,
인터럽트 처리가 끝나면, 다시 Running 상태로 돌아가 실행할 수도 있다.

왜 PINNED 상태를 이용하여 처리를 할까?

(모든 시스템이 어떤 상태를 가지고 있다라는 말은 이유가 존재하는 거다.)

1. 불필요한 프로세스 스위칭을 막는다.

PINNED 상태로 가서 잠시 대기하다가 다시 실행하는 것이다.

Solaris 시스템은 최신 버전의 UNIX 계열의 시스템이다.
UNIX도 프로세스 내부에서 OS를 실행시켜, 불필요한 스위칭을 막는 방법을 사용한다.
Solaris 시스템도 비슷한 방법인데, 프로세스 내부에서 OS를 실행시키진 않는다.
→ 별개의 커널 스레드로 실행하지만, 이 실행하고 있던 스레드를 그냥 쫓아내진 않는다.

2. 불필요한 Caching 작업을 줄인다.

만약 스레드를 쫓아냈다가 커널 작업이 굉장히 오래 걸려서 Ready Queue 로 보내는데,
Ready Queue 로 가게 되면, (만약 시스템에 CPU가 하나밖에 없다면, 아무 의미가 없겠지만) 시스템 안에 CPU가 10개쯤 있다고 하면,
현재 스레드가 CPU1의 작업을 하다가 Ready Queue로 갔을 때 마침 CPU2가 비어있어서 Ready Queue로 가자마자 다시 작업을 한다.
↔ 하지만 이러한 처리는 캐싱을 다시 해야하기 때문에 좋지 않다.

CPU가 바뀌면 캐싱 작업을 다시 해야한다.
→ 당연히 시간이 어마어마하게 걸리게 된다.

캐시라는 것의 효과?
→ 100번 중 95번은 캐시에서 데이터와 코드를 읽어서 해결할 수 있고,
5번 정도만 메모리에 가서 해결하면 된다.
캐시는 CPU와 속도가 거의 비슷하고 메모리는 속도가 어마어마하게 느리다.
⇒ 캐싱의 유무 에 따라 프로그램 실행 속도의 차이 가 커지게 된다.

⇒ Ready Queue 로 갔다가 다른 CPU를 실행시키느니,
차라리 Kernel 작업 을 하는 동안, PINNED 상태로 대기를 하다가 실행을 계속하면, 이미 캐싱이 되어 있는 상태이기 때문에 더 빠르다.


Linux Tasks

Linux는 멀티스레딩을 제공한다고 볼수도 있고 제공하지 않는다고 볼수도 있다.
애매하다.

Linux에서 Process = Task

Task는 아래와 같은 데이터 구조를 갖는다.

  • State
  • Scheduling information
  • Identifiers
  • Interprocess communication
  • And others

Linux Threads

Thread = Task = Process

1. Linux는 Thread와 Process를 구분하지 않는다.

Task 안에 스레드가 존재하는 것이 아니다.
⇒ Thread = Task = Process

2. User-Level Thread들은 Kernel-Level Process 들과 매핑된다.
(🌟)

User-Level에서 Thread를 하나 만들 때, Kerenl에서는 Thread가 만들어진 것이 아니라 Process가 하나 만들어 진 것이다.
⇒ 즉, 내가 Thread를 5번 만든 것은 시스템에서는 Process가 5개 만들어진 것과 같다.

3. 새로운 프로세스는 기존의 프로세스의 Attiribute를 Copy해서 생성된다.

4. 새로운 프로세스는 Cloned라는 명령어로 만들어져서 Resources를 공유한다.

프로세스를 fork() 로도 만들 수 있고, clone() 으로도 만들 수 있는데
clone() 으로 만들면, Resources를 공유한다.

5. Clone() 은 Task 별로 별도의 Stack 공간을 만든다.


Linux에서 Clone() 과 Fork()

⇒ 자원과 실행을 구분한다.

Fork()

Process 이미지 그대로 Copy하여 새로운 Task를 생성한다.

Clone()

Program code, data, ... 자원 과 관련된 정보는 Task1과 공유 하고,
실행 과 관련된 정보(Stack)만 새로 생성 한다.

Thread 가 생성된 것 같지만, OS는 Process와 Thread를 구분하지 않는다.
⇒ Kernel 입장에서는 프로세스(Task)가 3개 실행되고 있다.

⇒ 통신할 때 시간이 적게 든다.
↳ Multi-Threading 과 같은 효과가 있다.
Multi-Threading 을 지원한다고 봐도 무방하다. (같은 시간이 소요된다.)


Linux Process/Thread Model

Ready ↔ Executing

Ready 상태로 대기하다가 Dispatching 이 되면,
Executing Running 상태가 된다.

Timeout에 의해서 또는 우선순위가 더 높은 Task에 의해서 다시 Ready 상태로 돌아간다.

Executing → Zombie

실행을 다 마치면 Zombie 상태가 된다.

Executing → Stopped

실행을 하다가 Suspend가 되면 Stopped 상태가 된다.

Blocked

Linux는 Blocked 상태를 두가지로 관리한다.
Uniterruptible 과 Iterruptible 은 둘 다 Blocked 상태이다.
→ 명령 과 Block의 이유 에 따라 달라진다.

프로그램을 실행하다가 scanf 명령어를 입력해서 입력을 받으려고 준비를 할 때,
내가 입력을 줘야하는데 ctrl C를 누르게 되면,
해당하는 Thread가 Blocked 상태에 있었다가 ctrl C 를 누르면 Blocked 에서 풀려나서 Ready 상태로 이동하게 된다.
그 뒤, 다시 실행을 하면 ctrl C 를 왜 눌렀는지에 따라서 실행이 되기도 하고, 종료가 되기도 한다.

Blocked → ctrl C → Ready → Running or Exit
↳ 중요한 건 입력을 받지 못했다는 것이다.

ctrl C: User Program에게 주는 명령어가 아니라 OS에게 보내는 명령어이다.
(OS에게 해당하는 프로세스로 시그널을 보내라는 명령어)

Iterruptible

Block 으로 대기하는 상태이다.
→ 내가 어떠한 목적으로 Blocked 되어 있는데, 외부 시그널이 오면 Blocked 된 상태에서 그냥 포기하는 것을 Interruptible 상태라고 한다.

Uninterruptible

Block 상태로 대기되어 있는데, 이 Block 문제가 해결되기 전까지는
절대 깨어나지 않는 상태이다.

반응형
작성일
2023. 4. 3. 21:44
작성자
ssun_bear
반응형

fork()

Parent Process가 Child Process를 만들라는 명령어

→ Child Process는 Parent Process의 모든 코드를 copy해간다.

int main(){
	int i;
    
    fork();
	for(i=0;i<10;i++) {
		printf("%d....id=%ld\n", i, getpid());
    	sleep(1);
	}
    return 0;
}

위의 프로그램은 시작하자마자 Child Process를 하나 만들고 시작한다.

자식 프로세스는 부모 프로세스의 코드 모든 것을 복사하기 때문에 자식도 for문을 돌린다.

→ 즉 for문을 두 개의 프로세스가 각각 0부터 9까지 출력한다.

Process가 fork 되면 본인 프로세스가 부모인지 자식인지 알 수 없기 때문에 return 값이 0인지 1인지로 구분하여 판단한다.


Q. 하나의 Program이 하나의 Process인가? → X

하나의 Program은 m개의 Process를 가질 수 있다.

Q. 하나의 Process는 하나의 Program에 속하는가? → X

하나의 Process는 A, B, C, ... Program을 바꿔가면서 실행시킬 수 있다.

⇒ Process : Program = m : n

각각의 Process는 각각 별개의 실행 단위이다.
Ready Queue에 줄 서 있을 때 OS 입장에서 같은 프로그램에서 온 Process인지는 중요하지 않다.
OS는 어떤 프로그램에서 온 애를 구별하지 않고 각각 독립적인 프로세스로 판단한다.


Process가 아니라 Thread가 여러개 생성된 경우
: MultiThreading

  1. 실행하는 Process는 한가지이다.
  2. 두 개의 Thread는 하나의 같은 Process 안에 들어 있다.
    → 각각의 Thread가 독립된 실행 단위로 Ready Queue에 들어가 있으면, OS는 같은 Process에서 나왔는지 확인하지 못한다.
  3. Process가 만들어질 때 Code, Data, PCB, Stack 가 만들어지는데,
    다른 Process에서는 서로 다르다.

    하지만 Process가 같으면 하나의 Process에서 만들어진 Thread끼리는 Code, Data(전역 변수), PCB, Stack를 모두 공유한다.
  4. Multi Threading에서는 한 프로그램 안에서 여러 function들을 동시에 실행시킨다.

Thread = 별개의 실행단위로, 하나의 Process 안에 들어있다.

  1. Process가 독립적으로 Ready Queue에 들어간다.
  2. OS가 Process를 실행시키는 순서를 계속 바꿀 수 있다.
    → 이는 Process가 독립적이고 별개이기에 가능한 것이다.
  1. Thread가 독립적으로 Ready Queue에 별개의 실행단위로 들어간다.
  2. OS가 Thread를 실행시키는 순서를 계속 바꿀 수 있다.
  3. Thread는 같은 프로그램 Set를 공유한다.

Processes and Threads

3장 Process

(3장에서 배운 프로세스 기반의 시스템 기준, Multi Threading을 지원하지 않는 시스템)

  1. Scheduling, Execution의 단위
  2. Resource Ownership의 단위 (자원 할당)

4장 Process

(Multi Threading을 지원하는 시스템)

  1. SchedulingExecution 은 Thread 의 단위이다.
    Thread = Light Weight Proces
  2. Resource Ownership 은 Process 의 단위이다.
    Process = task

⇒ 자원 할당은 Process 기준이고, 실행은 Thread 기준이다.

 


Multithreading

Multithreading이 가능한 시스템은 언제부터 나오기 시작했는가?

OS는 기본적으로 하나의 프로세스에서 여러 개의 스레드를 지원한다.

  1. MS-DOS는 한 번에 하나의 Process에 하나의 Thead로 실행한다.
  2. UNIX는 여러개의 Process에 하나의 Thread로 실행한다.
  3. Windows, Solaris, modern version of UNIX는 여러개의 Process에 각각에 여러개의 Thread로 실행한다.
  Process Thread
MS-DOS 1 1
UNIX N 1
Windows, Solaris, modern version of UNIX N N

 


Threads and Processes


Processes

이전에 배웠던 Process Image를 Multithreading에서는 모양이 바뀌기 때문에 더이상 사용할 수 없다.

MultiThread가 가능한 환경에 놓여있는 Process

  1. Process는 자원할당의 단위와 Protection의 단위이다.
    ⇒ 자원 → A Process에 할당 → A Process와 A의 Thread들만 자원에 접근이 가능하다.
  2. Process는 Process Image를 저장하는 virtual address space이다.
    → 즉, Process는 Process Image를 포함한다.
  3. Process는 CPU, 다른 Process들, file들 그리고 I/O 자원들에 대한 접근을 Protect 하는 단위가 된다.
    → 하나의 프로세스와 그 프로세스에 들어 있는 스레드끼리는 권한(READ, WRITE, ...)이 동일하지만 다른 프로세스와는 권한이 다르다.

Process A가 CPU를 얼마나 쓰고 있다고 얘기하지,
Thread A가 CPU를 얼마나 쓰고 있다고 얘기하지 않는다.


Threads

  1. 실행 단위이다. (running, ready, etc.)
    Thread들의 상태는 각각 다를 수 있다.

  2. Running 상태가 아닐 때, Thread Context를 저장한다.
    → CPU의 상태를 Context로 저장한다.
    ⇒ Thread는 Thread Context를 각자 가지고 있어야 한다.
    (Context는 PCB의 정보 중 하나이다.)

    Thread1 → Timeout, Thread1 Context 저장 → Thread2 → Timeout, Thread2 Context 저장 → Thread3
  3. Execution Stack을 가진다.
    (Execution Stack은 PCB의 정보 중 하나이다.)
    ⇒ 즉, Thread는 Stack 모양이 다 다르다.

    Thread1 → A 호출 → B 호출
    Thread1은 Stack에 A, B에서 사용한 지역 변수 O
    !=
    Thread2 → C 호출
    Thread2은 Stack에 C에서 사용한 지역 변수 O

  4. Thread별로 지역 변수를 위한 static storage를 가진다.
    multithreading을 할 때 스레드를 두 개 만들어서 A라는 함수를 호출하라고 할 때,
    A에 스태틱 변수가 있으면,
    스레드 A가 계산한 스태틱 변수의 값과 스레드 B가 계산한 스태틱 변수의 값이 같을 수가 없다.

  5. Thread의 memory 공간 과 resources 공간에 대한 접근을 할 수 있다.
    → Process의 모든 Thread들은 자원을 공유한다.

Single Threaded and Multihtreaded Process Mode

Single Thread Process Model

  • User Address Space에는 프로그램 데이터와 코드가 들어있다.
  • Kernel code가 User Process안에서 실행되는 시스템이다.

 

Multithreaded Process Model

 

스레드 별로 관리가 되는 것
→ Stack

Process별로 관리가 되는 것
⇒ 스레드가 공유하는 것 (프로그램 코드와 데이터 영역)

 

Single Thread PCB = Multithread PCB + TCB

 

  • 3강의 Single Thread의 PCB ≠ 4강의 Multithread의 PCB
  • Single Thread의 PCB = 4강의 Multithread의 PCB + 4강의 Multithread의 TCB

PCI (Program Control Information)

Single Thread에서의 pci는 실행 시 관리되어야 하는 정보와 자원관려하여 관리가 되어야 하는 정보 가 들어 있다.

프로세스를 실행시키고 관리하는데 필요한 모든 정보가 여기 들어 있다.

Multithread에서의 pci는 PCB와 TCB로 나누어 진다.

  • PCB의 pci는 자원을 관리하게 되고,
    ex: CPU를 얼만큼 사용했다, ...
  • TCB의 pci에서는 실행관련 정보를 관리하게 된다.
    → 스레드 단위로 관리된다.
    ex: 스레드의 상태(Ready, etc...), scheduling할 때 우선순위, ...

PI(Program ID)

Program을 실행하게 되면 Process가 되어 여러 스레드를 관리하게 되는데,
이 때 생성되는 스레드들은 전부 Owner가 동일하다.

⇒ 스레드 하나하나마다 Owner가 다를 수가 없기에, PI는 Process 단위로 관리가 된다.

 


Remote Procedure Call Using Thread

Thread를 사용해야하는 이유?
→ 프로그램의 실행 속도 향상!

Q. 여러개의 child Process로도 동시 작업할 수 있는데 왜 Multithread 로 동시작업을 할까?

이유? Process 생성 시간 > Thread 생성 시간

프로세스 생성 → 모든 것을 copy 해야한다.
프로  독립된 구조체이다.
즉, 프로세스는 복사하게 되면 많은 양의 정보들을 복사해야하기 때문에 생성시간이 길어진다.

⇒ 생성시간도 길어지게 되고, 없앨 때도 메모리, 자원, 스위칭 시간 등등을 할당된 자원을 다시 반납해야 하기 때문에 소요시간이 길어지게 된다.


↔ 하지만, Thread는 프로그램 코드와 데이터를 Share 를 할 수 있기 때문에 모든 것을 copy할 필요가 없다.

⇒ 생성시간이 줄어들게 되고, 없앨 때도 소요시간이 줄어든다.

 

multi-threading 을 해도,
어차피 CPU가 하나라고 한다면, 1번 프로세스의 1번 스레드를 실행하다가 Timeout이 됐을 때, 그 다음에 2번 프로세스의 2번 스레드를 실행하면 당연히 프로세스 스위칭 을 해야 한다.

그런데, 1번 프로세스의 1번 스레드를 실행하다가 1번 프로세스의 2번 스레드를 실행하는 식으로 스레드만 바뀌는 경우인 스레드 스위칭 도 존재한다.

Thread1 → Timeout → Thread2

Thread 만 바뀌고 Process 는 변하지 않는다.
⇒ Thread 스위칭할 때가 Process 스위칭보다 저장정보가 적다.

Processor state information context 는 저장되어야 한다.
context말고도 다른 많은 정보들이 스위칭 할 때 저장되어야 한다.
스레드 스위칭을 하면, 프로세스 스위칭을 할 때 보다 다른 정보들을 저장하는 것이 줄어든다.


Thread의 장점 네가지

1. 프로세스 생성 시간 > 스레드 생성 시간 (🌟)

2. 프로세스 중단 시간 > 스레드 중단 시간

3. 프로세스 스위칭 시간 > 스레드 스위칭 시간 (🌟)

4. Kernel의 개입 X

Thread 는 같은 프로세스에서 메모리 와 파일 들을 공유 하기 때문에,
통신을 할 때 Kernel 이 끼어들 필요가 없다.
→ Kernel 이 끼어들게 되면, 시간 소요가 높아지게 된다.


Thread States

  1. Spawn
    ↳ Spawn another thread
    (≒ new, 프로세스가 생성되는 것과 같이 스레드가 만들어지는 상태)
  2. Ready
  3. Running
  4. Blocked
  5. Finish
    ↳ Deallocate register context and stacks
    (thread가 종료한 상태)

Process 종료 ≠ Thread 종료

실행을 하려면, Process는 무조건 하나의 Thread는 있어야 한다.
→ Process가 하나의 Thread로 실행을 시작한다.

Q. 왜 Multithread는 7개의 State Model로 나타낼 수 없을까? → X

MultiThread는 3장의 상태도(5개의 모델)과 같지만, 7개의 모델 상태도로는 그릴 수 없다.

7개의 상태에서는 Swapping 에 의한 Suspend 상태가 존재한다.
이 Suspend 가 일어나는 여러 이유 중 가장 큰 이유가 Swapping 이다.

 

MultiThread의 상태도

 

하지만 Thread 는 Swapping 이 불가능 하다.
→ Thread Suspend 가 일어나 Thread Swapping out 이 일어나는 것은 불가능 하다.

스레드가 실행하고 있었는데, 얘(스레드의 stack)만 딱 띄어서 스와핑 area로 보내는 것은 의미가 없다.

⇒ Process 를 Swapping out 해야 한다.
→ Process 가 스와핑의 단위이다.
Suspension은 Process 단위로 이루어진다.


Thread State vs. Process State

몇몇의 state들은 Process 단위에서 이루어진다.

  1. 프로세스가 Swapping out 이 되어 Suspend 되면,
    이 프로세스에 속한 모든 스레드들도 Suspend 되어 swapping area 에 놓여지게 된다.
    →  모든 스레드들이 같은 address space 를 공유 하기 때문이다.
  2. 프로세스의 Temination 은 프로세스 내부의 모든 스레드들을 멈추게 한다.

여러개의 스레드 중 1개가 외부 자원 접근 시도
↳  OS가 위험을 감지하고 이 스레드를 포함한 프로세스 전체를 강제 종료(termination)하게 된다.

⇒ Termination 작업과 Swapping 작업은 Process의 단위 로 이루어지는 작업이고,
Thread 의 상태가 아닌, Process 의 상태로 이루어진다.

 

Suspend가 발생하는 이유 5가지

single thread의 경우
suspend가 발생하는 이유는 swapping만 있는 것이 아니다.
그 중, thread에 의해 suspend가 발생하기도 한다.

  1. 스레드 간의 동기화
    어떤 스레드는 다른 스레드가 작업할 때 동안 잠깐 멈춰 있어야 한다.
  2. User request
    어떤 스레드는 다른 스레드가 작업할 동안 잠깐 멈춰 있어야 한다.
  3. Sleep(1)과 같이 스레드가 1초동안 작업을 하지 않는 것
    이런 문장들이 있으면 해당 스레드를 suspend 시킨다.

⇒ Suspend → 메모리에 있을 필요가 없다. ⇒ Swapped out
↔ process가 더 많은 스레드를 가지고 있다면 괜찮다.

스레드가 3개가 있는데, 3개의 스레드 중 하나가 동기화 때문에 suspend가 되어야 할 때, 아직 2개의 스레드를 더 실행할 수 있기 때문에 이 프로세스를 Swap out을 할 필요가 없다.

Suepend ← Process 단위

⇒ Suspension = swap out

Suepend ← Multi Thread 단위

⇒ 한 프로세스 안에 여러개의 스레드가 존재할 수 있다.
여러 스레드 중 1개 동기화로 인한 Suspension
→ 아직, 나머지 스레드들이 실행을 할 수 있다. ⇒ Swapout X

  • Thread의 Suspend → Process의 Suspend가 될 수도 안 될수도 있다.
  • Process의 Suspend → 이 Process에 포함된 모든 Thread의 Suspend 무조건 된다.

User-Level Threads

1. Thread Library 가 포함하는 코드

  • 스레드를 생성 하고 삭제 하는 코드
  • 스레드 간의 메시지와 데이터 전송 을 위한 코드
  • 스레드 실행 스케쥴링 을 위한 코드
  • 스레드 context를 save 하고 restore 하는 코드

User level에서는 Library를 통해 Multi Thread가 가능하다.

User-Level Thread Library

User level 스레드는 실제로 시스템에서는 멀티 스레딩을 지원하지 않는데,
유저 레벨에서 스레드 라이브러리를 만들어서 여기서 스레드를 만들고 그 다음에 스케쥴링하고 스위칭하고 종료하고 하는 등의 관리를 한다.

→ User level에서 Thread Library를 만들어 스레드를 스케쥴링하고 Switching을 한다.

Q. 스레딩 관리를 한다?

→ 유저 레벨의 스레드 라이브러리에서 스레드를 관리한다.
스레드 관리 = 스레드를 만들고 종료하고 스케쥴링하고 스위칭하는 것.

2. 어떠한 application도 Thread Library 를 사용해 MultiThread 하게 프로그램되어질 수 있다.

3. Kernel은 Thread의 존재를 알지 못한다.

  • Kernel Level에서는 Multi Threading을 지원하지 않는다.
  • Kernel Level은 하나의 Process 단위로 관리된다.

  • 커널 레벨에서는 하나의 프로세스만 실행되는 것 처럼 보인다.
  • 유저 레벨 프로그램 안에서는 스레드 라이브러리에서 멀티 스레딩이 되어 여러 개의 스레드가 돌아간다.

Relationships between User-Level Thread

실제 Kernel은 Process 단위로 지원한다.

(a) Process Running

두 개의 스레드가 User level에서 관리된다.
하나는 Ready 상태, 하나는 Running 상태이다.
Kernel에서는 이 프로세스가 실행되고 있는 상태이다.

(b) Process Blocked

→ Thread 2가 실행중
→ Thread 2가 I/O 요청
→ Process B가 Blocked 상태가 된다.
↔ 그런데 Thread2는 여전히 Running 상태이다.

스레드는 User Level에서 진행된다.
⇒ 프로그램의 일부이다.
스레드 라이브러리에 가서 함수를 이용해서 상태변화를 시킬 수가 없다.
그냥 Process가 Blocked 된 것이다.

→ 나중에 실행을 재개할 때 스레드들의 상태를 수정하게 된다.

(c) Process Ready (Timeout)

Process의 Timeout
→ Thread2의 실행 중 Timeout
→ 당연히 Kernel에서는 이 프로세스를 Ready 상태로 옮긴다.
→ 그러나, 스레드 라이브러리는 실행을 하다가 갑자기 중단이 되어버렸으니까, 당연히 스레드의 상태변화를 수정을 할 시간이 없다.
→ 따라서 아직 상태변화가 안된 것 처럼 보인다.

→ 나중에 실행을 재개할 때 스레드들의 상태를 수정하게 된다.

(d) Process Running, Thread2 Blocked

실제로는 프로세스가 계속 실행을 하고 있고,
원래 Thread2가 I/O 작업등을 요청을 하려고 했는데, 스레드 라이브러리에서 명령을 받아보고,
이걸 받아주면 내가 Blocked 이 되겠구나 생각을 해서 Thread를 스위칭 한 것이다.
→ Thread2를 Blocked 상태로 옮기고, Thread1을 Running 상태에서 실행을 하게 만든다.
↳ Kernel에서는 Thread가 바뀐 것을 모른다.

⇒ Thread Switching 은 User Level 에서 진행된다.

Kernel 과 상관 없이 User Level 에서
Thread Switching , Thread Scheduling 이 가능하다.

 


Kernel-Level Threads

당연히 Multi-Threading을 OS가 지원한다.
OS가 지원하기 때문에, kernel에서 스레드를 생성, 삭제, 스케줄링하고 스위칭하는 작업이 가능하다.

Thread가 여러개라고 해도 CPU가 한 개이면, 어차피 번갈아가며 작업을 해야한다.
⇒ 멀티 스레드 시스템이 더 빠르다는고 확실히 말할 수 없다.

↔ CPU가 여러개라면 진짜로 동시 실행이 가능해진다.

⇒ Kernel-level thread와 User-level thread의 차이를 얘기할 때 꼭 여러개의 CPU를 갖는 시스템에서의 실행을 얘기해주어야 한다.

당연히 이 스레드들은 별개의 실행 단위이기 때문에 스레드 하나가 blocked이 되었다고 해도 다른 스레드가 계속 실행을 할 수 있고,
이러한 장점들이 있는 반면에 여기서의 Switching은 진짜 Switching이다.

  1. 모든 스레드 관리 작업은 kernel에 의해서 진행된다.
  2. kernel은 여러개의 cpu에서 같은 프로세스로 부터 동시에 multiple thread를 scheduling 할 수 있다.
  3. 만약 프로세스의 하나의 스레드가 blocked되면, kernel은 이 프로세스의 다른 스레드를 schedule 할 수 있다.
  4. 스레드 스위칭은 kernel을 요구한다.

3개의 user level thread를 만들어서
kernel level에서 3개의 kernel thread를 만들어서 3개의 user level thread를 실행한다.


User-Level Threads vs. Kernel-Level Threads

시스템에서 Multi-Threading 을 지원한다.
→ 당연히 Kenel-level 에서 Thread 를 사용하는 것이다.

시스템에서 Multi-Threading 을 지원하지 않는다.
→ 그런데 나는 프로그램을 Multi-Thread를 사용해서 작성하고 싶다.
→ User-level 에서 Thread를 사용할 수 밖에 없다.

 

그러나 시스템에서 Multi-Threading 을 지원한다 하고,
그런데 나는 Kenel level thread 를 안쓰고 User-level thread를 사용하겠다.
↳ User-Level 이 갖는 장점이 존재한다.

User-Level threads 장점

  1. Thread Switching 할 때, kernel mode 권한을 요구하지 않는다.
    ↳ kernel이 아니라 User-level에서 스위칭을 한다.
    진짜 스위칭 X, 스위칭하는 것 처럼 보이게 하는 것이다.
    → OS가 개입하지 않으므로 스위칭 하는 시간이 줄어든다.
  2. Scheduling은 application specific 할 수 있다.
    ↳ 시스템 단위의 스케쥴링이 존재한다.
    어떤 경우에는 이 프로그램은 그렇게 스케쥴링하면 효율성이 떨어질 수 있다.
    즉, 이 애플리케이션에 맞는 스케쥴링을 하고 싶을 때, User-level의 스레드를 사용할 수 있다.
  3. ULTs 는 어떠한 OS에서도 실행될 수 있다.
    OS가 Multi-Thread를 지원하든, 안하든 상관 없이 항상 사용할 수 있다. 🌟

Kernel-Level threads 장점

  1. CPU가 여러개가 있으면, 정말로 동시에 실행이 될 수 있다. 🌟
  2. 만약 하나의 스레드가 blocked되면, 또 다른 스레드가 이용될 수 있다.
  3. Kernel 자체를 Multi-Threading 할 수 있다. 🌟
    OS를 멀티스레드를 만들어서 SMP 머신에서 실행하는 것이 멀티 스레드의 원래의 목적이다.
    → 멀티 프로세서와 함께 나왔다.
    → 여러개의 CPU + OS를 여러군데에서 동시에 실행
    → 멀티 스레딩을 이용해서 OS를 동시에 실행시키는 것

  • 포크하는데 걸리는 시간
  • 통신하는데 걸리는 시간

단위 → 마이크로 세컨드


Combined Approached for Thread

System level에서 multi programming을 지원함에도,
user-level thread와 kernel level multi-thread를 함께 사용하는 것.

커널 입장: 프로세스 두개 실행 중

  1. 스레드 2개인 프로세스 A - User level thread 3개
  2. 스레드 1개인 프로세스 B - User level thread 1개

Q. 왜 이렇게 커널레벨과 유저레벨 스레드 두 가지를 다 사용하는가?

간단히 말하면, 커널레벨의 스레드의 장점과 유저 레벨 스레드의 장점을 둘 다 얻고 싶은 것이다.

  • 커널레벨의 스레드의 장점
    (여러개의 CPU를 갖고 있는 시스템에서 한 프로그램 안에 있는 여러 스레드를 진짜로 동시에 실행시킬 수 있다.)
  • 유저 레벨 스레드의 장점
    (스위칭을 할 때, 소요시간이 적게 걸린다.)

Q. Combined Approached for Thread 을 사용하는 진짜 이유?

멀티스레딩 → 스레드가 항상 동시에 실행되진 않음
User가 불필요하게 너무 많은 스레드를 만들 수 있는데, 이를 OS가 관리할 수 있다.
⇒ 불필요하게 많은 스레드를 만드는 것을 막기 위하여 이렇게 두 단계로 진행하는 것이다.

 

반응형
작성일
2023. 4. 1. 14:19
작성자
ssun_bear
반응형

기초 쿼리 문법

1. 작성 순서

SELECT - FROM - WHERE - GROUP BY - HAVING - ORDER BY

SELECT (컬럼명)

FROM (테이블명)

GROUP BY(항상 WHERE 뒤) : 그룹화하여 단일 값으로 축소함

HAVING(항상 GROUP BY 뒤) : 그룹화 조건 확인 (count등이 쓰임)

 

2. 많이 쓰이는 함수 모음

  1. DATE_FORMAT(시간값, 원하는 포맷) : 날짜형식 지정
    1. Y : 2022, y : 22
    2. M: september, m:09, a: Sep
    3. d:23(일자)
    4. T : hh:mm:ss
예시
SELECT DR_NAME, DR_ID, MCDP_CD, DATE_FORMAT(HIRE_YMD, "%Y-%m-%d") AS HIRE_YMD 
FROM DOCTOR WHERE MCDP_CD = "CS" OR MCDP_CD = "GS" 
ORDER BY HIRE_YMD DESC, DR_NAME ASC

 

2. DATEDIFF(날짜1, 날짜2) : 날짜간의 차이

    1. 현재 시간
    2. DATEDIFF(**CURRENT_DATE()**, DATETIME)

3. TIMESTAMPDIFF(단위, 날짜1, 날짜2)

1. 단위 : SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER(분기), YEAR

4. CASE, WHEN-THEN

1. 형식

SELECT 쪽에서 많이 쓰임
(CASE 
WHEN “조건”
THEN “반환값” 
WHEN “조건2”
THEN “반환값2” 
ELSE “WHEN조건에 해당 안되는 경우 반환할 값” 
END ) AS “반환값으로 이루어진 추가될 컬럼명”

 

5. LIKE : 원하는 데이터 검색

    1. 형식
    2. SELECT * FROM A_TABLE WHERE TITLE LIKE "%아디다스%"
    3. A_TABEL의 TITLE 컬럼명에 아디다스라는 말이 있는 것을 뽑아옴 (주변에 무슨 숫자, 문자열이 몇개 있든 상관없음)

6. SUM / COUNT

    1. 평균값 계산하기
    2. 심화 : 소수점에서 반올림 → ROUND
    3. 형식
SELECT ROUND(SUM(DAILY_FEE)/COUNT(*), 0) AS AVERAGE_FEE

7. JOIN

    1. 예시
SELECT a.FLAVOR 
FROM FIRST_HALF AS a RIGHT(LEFT) 
JOIN ICECREAM_INFO AS b ON a.FLAVOR = b.FLAVOR -> 해당 키값을 기준으로 묶음 
WHERE a.TOTAL_ORDER > 3000 AND b.INGREDIENT_TYPE = "fruit_based" 
ORDER BY a.TOTAL_ORDER DESC

8. ORDER BY 의 기준이 여러개일때 ( , 쉼표로 붙여서 해결가능!)

    1. ORDER BY TOTAL_ORDER DESC, SHIPMENT_ID ASC
    2. → 순서대로 우선순위임

9. 데이터 정렬 개수

    1. 예시
SELECT * FROM 테이블명 ORDER BY 기준컬럼 DESC LIMIT 3 ( 0번째부터 3개 내림차순 출력)
 

10. SELECT하고자 하는 컬럼에 데이터가 없는 경우

    1. 만약 “NONE”으로 출력하고 싶다면
SELECT PT_NAME, PT_NO, GEND_CD, AGE, IFNULL (TLNO, "NONE") AS TLNO 
FROM PATIENT 
WHERE AGE <= 12 AND GEND_CD = "W" 
ORDER BY AGE DESC, PT_NAME

+) IF (조건문, “참일경우 반환값’, “거짓일경우 반환값) AS 컬럼

11. MAX, MIN

    1. 예시
SELECT MAX(COLUMN) 
FROM A_TABLE 

SELECT MIN(COLUMN) 
FROM A_TABLE

12. WHERE <컬럼> IS NULL / IS NOT NULL

    1. 문제 예시
<나이 정보가 없는 회원 수 구하기>
 SELECT COUNT(*) AS "USERS" 
FROM USER_INFO 
WHERE AGE IS NULL 

<나이 정보가 있는 회원 수 구하기>
SELECT COUNT(*) AS "USERS" 
FROM USER_INFO 
WHERE AGE IS NOT NULL
 
반응형
작성일
2023. 3. 31. 22:15
작성자
ssun_bear
반응형

OS의 실행방식 세가지

1. Non-process kernel

  1. OS Kernel을 별개의 객체로 보는 방식이다.
  2. 각 Process 관리 방식 != OS kernel 관리 방식
  • OS는 특별한 권한을 가지고 있다.
  • OS는 별개의 entity로 시스템 안에서 실행되는 객체이다.
  1. OS가 작아서 OS전체가 Memory에 올라갈 수 있던 옛날에 가능했던 방식이다.
  2. OS가 작아서 전체가 Memory에 올라가, Virtual Memory를 사용할 필요가 없다.

2. Execution Within User Processes

  1. OS를 User Process 안에서 실행시키는 방식이다.
  2. OS에서 굉장히 중요한 부분 빼고, 나머지 부분들을 Process 안에서 실행 시킨다.
  3. P1 ~ Pn까지 User Process안에 OS function이 들어있다.

User Program

모든 프로세스 = Process Control Block + User Stack + Private User Address Space

실행 → 인터럽트 발생 → mode switching(process switching X)

PCB가 필요한 이유:

메모리가 한정적이기 때문에, Program이 끊겼다 다시 실행하다 반복하고, 메모리를 나누어 쓰기 때문에 PCB 정보가 필요하다.
PCB는 내가 다른 프로그램과 함께 실행하기 때문에 필요한 정보들이다.
혼자 메모리를 쓰면 필요가 없다. 자원을 공유해야하기 때문이다.

Kernel Stack

OS 실행 → Kernel Stack에 OS가 Stack을 쌓았다 뺐다 하면서 실행한다.

Shared Address Space

모든 User Process는 OS코드, OS Data를 Share한다.

이 프로세스 안에 Shared Address Space가 들어 있고, Shared Address Space안에 OS 코드와 Data가 들어 있다.

프로그램 실행
→ 코드 변화 X, Data 영역 변화 O(데이터 영역의 값 변화 O, Data 모양 자체의 크기 변화 X), Stack 변화 O

 Process Switching이 필요 없는 OS 실행 방식이다.
 mode Switching만 발생한다. ⇒ 속도↑

위에서는 User Program 아래서는 Kernel Program이 실행될 수 있다.

3. Process-Based Operating System

  1. OS도 다른 프로세스랑 똑같이 별개의 Process로 관리한다.
  2. OS = User Process
    micro kernel을 제외하고 나머지는 Process 처럼 처리한다.
  3. CPU가 서로 다른 OS의 function들을 동시에 실행시킬 수 있다.
    ⇒ 확장성이 좋다.
  4. 단점: OS도 프로세스이기에, 실행시키기 위해서는 Switching이 발생되어야 한다.
    Switching이 발생하면 속도가 느려지게 된다.
    P1 → OS1 입출력 요청 → OS2 호출
    ⇒ Switching이 많이 발생하게 된다. ⇒ 속도 ↓


UNIX SVR4 Process Management

1. OS의 실행방식:

Execution Within User Processes + Process-Based Operating System (위의 두번째 방식 + 세번째 방식)

대부분의 OS 프로그램들은 User process 안에서 실행시킨다.

2. 프로세스들의 두가지 카테고리

System Process

별도의 Process로 OS 관리

  • 0: Swapper
  • 1: init
  • Process Tree

User Process

User Process 안에서 OS 관리


Process Description

프로세스 이미지

  1. Program Code
  2. Data
  3. Stack
  4. PCB
    • Process ID
    • Process State Information
    • Process Control Information

PCB를 다음과 같이 나눈다.

User Level Context

  1. Process text
    = program code
  2. Process data
  3. User stack
  4. Share memory
    여러 프로세스들이 같이 사용하는 공용 공간

UNIX에서는 User Process 안에서 OS가 실행되기 때문에,
User Stack  Kernel Stack 두가지 스택을 가지고 있다.

이 중, User Stack  User Level Context 에 속한다.
Kernel Stack  System Level Context 에 속한다.

Register Context

Process Image 기준으로 봤을 때,
PCB 안에 들어 있는 Processor State Information 이라고 볼 수 있다.

  1. Program Counter
  2. Processor status register
  3. Stack pointer
  4. General-purpose register

System Level Context

  • Kernel Stack이 이에 속한다.
  • Process ID, Process Control Information이 들어있어야 한다.

OS가 User Process 안에서 실행이 되는데, 별도의 Process로 실행되기도 한다.
User Process 안에서 실행이 되고 있는 동안, access해도 되는 정보와 나머지 정보를 분류해 놓는다.

  1. U(user) area
    → OS가 User Process 안에서 커널이 실행이 될 때, access하는 정보들이다.
  2. Process table entry
    나머지 Process control informaiton 들은 Process table entry에 별도로 저장을 해놓았다.
  3. Per process region table
    → 메모리 관리와 관련 O
  4. Kernel Stack

Unix에서의 프로세스 상태도

New → Created 상태

메모리 충분 → ready to run in memory

메모리 불충분 → ready to run swapped (ready/suspend)

 

ready → running

 

종료 → exit → Zombie

모든 시스템은 종료를 하면 시스템에서 사라지는 것이 아니라, 자기의 Parent의 Process 한테 자기가 어떻게 종료했는지 종료 상태를 보고해야 하는 의무가 있다.

프로세스가 사라지면, Memory도 다 반납하고, 자기가 받은 자원을 다 반납을 해도, 프로세스 테이블에 Entry 하나를 남겨둔다.
프로세스 ID + 종료 상태
이걸 자신의 Parent가 확인을 해주어야만 사라질 수 있다.

즉, 좀비 상태는 확인을 안해서 계속 남아있는 상태이다.

실행 → I/O 작업 → 프로세스 실행 불가 → Asleep in Memory(Blocked 상태) → Sleep, Swapped(Blocked/Suspend)
→ I/O 완료 → ready to run swapped (ready/suspend)
→ swap in → ready to run in Memory

 

앞에서의 모델과 다른 한가지는, Blocked/Suspend에서 Blocked 상태로 이동하는 모델이 있었는데, Unix에서는 없다.
한 번 하드디스크로 Swapped 되면, 다시 Swapped 될 때까지 Memory로 올라오지 못한다. Ready/Suspend를 거쳐서 Ready로 올라와야 한다.

Running 상태

= User Running + Kernel Running

Running이 2개 필요한 이유?

Kernel 코드가 User process 안에서 실행이 되는데,
User Process가 실행이 되는데
어떤 때 User Program을 실행하는 User Running 상태이고
어떤 때는 Kernel Program을 실행하는 Kernel Running 상태가 된다.

User Running

  1. User Program 코드가 실행이 된다.
  2. Process State: User Running 상태
  3. CPU mode: User mode

Kernel Running

  1. OS가 User Program 안에서 실행이 된다.
  2. Process State: Kernel Running 상태
  3. CPU mode: Kernel mode

항상 User Programming 실행을 하려면, Kernel 작업이 필요하다.

Kernel Running → User Running

User Running → Interrupt, System call → Kernel Running

  • Time Interrupt → Ready 상태로 보냄
  • I/O 작업을 위한 System call → Blocked 상태로 보냄
  • 다시 Running 하는게 맞을 경우 → User Running 상태로 보냄

⇒ 불필요한 Switching이 존재하지 않는다.
(Mode Switching은 존재한다.)

Ready 상태

= Ready to Run In Memory + Preempted

Kernel이 작업을 막하다가,
Timeout Interrupt 발생 → Preemted 상태

--- 뜻

Ready to Run In Memory, Preempted 둘 다 Ready Quque에 들어 있다는 뜻이다.

Preempted

Running을 하다가 Preempted로 이동한다.
Preempted에는 원래 Running 상태로 실행하고 있던 Process 가 Timeout이 되면 이동하게 되는 곳이다.

원래 실행을 하고 있던 프로세스들이기 때문에 OS가 해줘야 하는 일들이 적다.

Ready to Run In Memory

이런 저런 이유로, 한동안 실행을 못하다가 다시 실행을 시작해야하는 프로그램이 들어 있다.
이런 경우에는 OS가 해줘야 하는 일들(메모리 관리, ...)이 많다.

⇒ 둘 다 Ready 상태이고 Ready Queue에 넣어 놓지만, 다시 실행할 때 해야하는 일들이 달라서 구분해 놓은 것이다.

Q. Preemted → User Running 이런 화살표가 존재하는 이유?

원래는 이런 화살표가 존재할 수가 없다.
User 프로그램이 실행이 되려면, 당연히 OS가 뭔가 작업을 해주어야 User Program이 실행이 된다.
OS의 작업 없이 User Program이 갑자기 실행을 시작할 수는 없다.

모든 프로그램은 실행을 시작하려면 Kernel Running 상태를 거쳐야 한다.
Preemted에서 User Running 로 갈때도 당연히 Kernel Running 상태를 거쳐야 한다.

근데 이 모델은 시스템 전체가 아닌, 하나의 프로세스에 대한 모델로,
하나의 프로세스가 어떻게 변화하는지 나타낸 그림이다.

Preemted에 존재하는 프로세스는 이미 Ready to Run In Memory에서 Kernel Running을 거쳐 User Running 상태에서 실행이 되다가 Time Interrupt를 거쳐 Preemted 상태로 오게 된 애들이다.
따라서 다시 실행될 때 문제가 없다면, Kernel을 거치지 않아도 바로 실행될 수 있는 것이다.

반응형

'Computer Science > 운영체제' 카테고리의 다른 글

Chapter 4-2. Threads  (0) 2023.04.04
Chapter 4.1 Threads  (0) 2023.04.03
Chapter 3-2. Process Description and Control  (0) 2023.03.31
Chapter 3-1. Process Description and Control  (0) 2023.03.31
Chapter 2-2. Operating System Overview  (0) 2023.03.26
작성일
2023. 3. 31. 17:10
작성자
ssun_bear
반응형

  • OS 또한 Program이기에 Memory의 공간을 차지한다.
  • tree가 pointer와 연결되어 있다.
  • Primary Processiable 또한 OS에서 관리한다.
  • Swapping Area에는 하드디스크일지라도 File Area에 들어 있는 실행 파일과 다르게 Code + Data + PCB + Stack이 모두 포함된 Process 상태로 저장되어 있다.

Process Description

OS가 Process를 어떻게 관리하는지가 중요하다.

Operating System Control Structure

1. 각각의 Process와 여러가지 Resource의 Current Status에 대한 정보를 관리한다.

2. OS는 System 내부 자원 관리를 위해 다음의 네가지 테이블을 만들어서 관리한다.

1. Memory Table
2. I/O Table
3. File Table
4. Process Table

당연히 OS가 프로그램이니까, 시스템 안에 있는 자원들을 관리하기 위해서 테이블 형태의 구조체 배열을 만들어서 관리를 한다.

(마치 우리가 프로그램을 작성할 때 입력 받은 데이터를 관리하기 위해서는 구조체 배열이 필요하듯이!)

 

4가지 테이블의 모양


Memory Tables

1. Allocation of main memory to processes

Memory의 x번지 ~ y번지가 어떤 Process에게 할당되어 있는지 적혀 있다.

2. Secondary memory (Hard Disk)

  1. Hard Disk의 x번지 ~ y번지가 어느 프로세스에 할당되어 있는지 정보가 적혀 있다.
  2. 실행파일은 File Table에서 다루고 Memory Table에서 다루는 것은 Process, Swapping Area이다.

⇒ 즉, Memory Table은 Swapping이 이뤄졌을 때 몇 번지~ 몇 번지까지에 저장되어 있는지에 대한 정보를 관리한다.

메모리 관리는 메인 메모리(Main Memory)와 하드 디스크의 Swapping Area 까지 포함한다.

3. Protection attributes for access to shared memory regions

시스템 안에는 Shared Memory Region 이 존재한다.

 

실제로는 몇개의 프로세스들이 데이터를 Share할 수 있다.
메모리 안에 있는 한 페이지가 여러 프로세스가 access할 수 있는 Shared Region일 수 있다.

 

→ 이 경우, 이 페이지에 접근할 수 있는 프로세스는 누구이고,
누구는 읽기도 할 수 있고 누구는 쓰기만 할 수 있고 이러한 정보들을 관리해야 한다.

 

당연히 이 Shared Region에는 Data 만 Share하는 것이 아니라,
Code 도 Share할 수 있다.

4. Information needed to manage virtual memory

Virtual meomry 관리에 필요한 여러가지 정보들이 담겨 있다.

 


I/O Tables

시스템 안에 있는 모든 I/O Devices들이 이 테이블에 올라가 있다.

1. I/O device if available or assigned

누가 있느냐, 누가 사용중이냐가 이 테이블에 올라와 있다.

2. Status of I/O operation

사용중인 경우, 누가 사용하고 있는지, 어디까지 사용했는지, ... Status 정보들이 들어 있다.

3. Location in main memory being used as the source or destination of the I/O transfer

출력

모든 I/O 작업은 메인 메모리 몇번지에 있는 데이터를 내가 출력할 때,
일단 I/O module 안에 있는 버퍼 몇 번지로 옮기고 그 다음에 출력한다.

데이터 출력: Memory → I/O buffer → I/O module

입력

입력을 받을 때 입력 데이터를 I/O 모듈 몇번지로 옮긴 다음에 그거를 메모리로 옮긴다.

데이터 입력: I/O module → I/O buffer → Memory

모든 I/O 작업은 메모리와 I/O Module안에 있는 I/O buffer 사이에서 왔다갔다 해야하기 때문에
→ 주소가 적혀있다.


File Tables

모든 파일들이 File Table 안에 들어 있다.

1. Existence of files

데이터 파일, 실행 파일, ... OS는 파일 유형을 구분하지 않는다.
⇒ 모든 파일들이 File Table 안에 들어 있다.

2. Location on Secondary memory(HDD)

당연히, Secondary Memory 안에 있으니까 하드디스크 몇번지에 있는지 정보를 가지고 있어야 한다.

3. Current Status

OPEN 가능 → 읽기, 쓰기
다음 번에 어느 위치를 읽을 것인지, 어느 위치에 쓸 차례인지
File Pointer를 관리해 주어야 한다.

4. Attributes

파일 크기, 누가 만든 파일인지와 같은 정보들을 관리해주어야 한다.


Primary Process Table

Attribute necessary for process management

지금 시스템 안에서 실행하고 있는 모든 프로세스가 전부 하나씩 Entry 로 들어가 있고,
실제 Process는 오른쪽에 Process Image 로 존재한다.

  1. 전체 프로세스 정보는 Process Image에 존재한다.
  2. Process Image는 Pointer를 통해서 접근한다.
  3. 프로세스 ID, ... 몇가지 정보들이 Primary Process Table에 존재한다.

Primary Process Table에 들어 있는 대표적인 정보

  1. ID
  2. Process Image에 대한 Pointer
  3. Process가 메모리 어디에 있는지 위치 정보

Q. Process "Image" 라는 용어를 사용하는 이유?

밑에 모든 것을 포함한 것을 Process Image라고 부른다.

 

하나의 Process는 Memory에 다 들어갈 수 없기 때문에,
Process의 일부만 들어가게 되는데, OS가 전체 Process가 Memory에 들어가 관리를 하는 것처럼 상상하여 사용하기 때문에 Process "Image" 라는 용어를 사용한다.

 

Typical Elements of a Process Image

1. User Data

프로세스는 프로그램 코드와 데이터(User Data)로 이루어져 있는데,

여기서 User Data는 전역 변수, Static 변수 프로그램이 시작해서 끝날때까지 계속 존재하는 변수이다.

이 변수들은 Compile이 되어 Binary Code가 생성될 때,
공간이 같이 만들어지는 변수들이다.

2. User Program

실행해야 하는 프로그램

3. Stack

프로그램이 컴파일이 되어서 바이너리 코드로 만들어질 때,
전역 변수나 Static 변수를 저장하는 공간은 같이 만들어지지만,
Local 변수를 저장하는 공간은 해당하는 함수가 호출될 때 생성된다.

 

Q. 미리 만들어 놓지 않고, 그때 그때 호출할 때 만드는 이유?

→ 내가 모든 함수를 다 동시에 사용하지 않는데,
모든 함수에서 사용할 변수의 공간을 미리 만들어 둔다면,
프로그램의 크기가 너무 커질 것이다.

 

실제로 함수는 한 번에 하나씩 호출이 된다.
→ 그래서 호출 됐을 때 필요한 딱 최소한의 공간만 만들어야 한다.
그러기 위해서 Stack 을 사용한다.

당연히 Stack 에는 함수 호출이 끝나고 Return 할 주소가 함께 들어있다.

4. Process Control Block

OS가 프로세스들을 관리하는데 필요한 모든 정보들이 들어 있다.


PCB에 저장되는 정보

1. Process Identification

(1) Process Identifier (Process ID)

OS가 Process를 만들 때 ID부터 생성한다.
시스템 안에서 Process끼리 ID가 겹치면 안된다.
⇒ Process는 유효한 ID를 부여 받게 된다.

(2) Parent Process Identifier

우리가 프로그램을 실행
↳ 시스템 입장 → A Process 실행
→ OS에게 B Process 실행해달라고 요청 → B Process 실행

 

A: Parent Process
B: Chid Process

 

Q. Tree 형태로 Process를 관리하는 이유?

→ A Process는 B Process를 만들고 끝나는게 아니라,
B Process가 제대로 종료되었는지 확인하고 OS에게 보고할 의무가 있다.

⇒ 즉, Parent Process ID가 PCB안에 저장되어 있어야 한다.

(3) User Identifier

여러사람이 같이 사용하는 Process의 경우에는 각 프로세스가 어느 User의 Process인지 구분해주어야 한다.

ex) 예를 들면, 학사정보시스템 로그인 → 학생 User ID로 프로세스가 진행된다.

⇒ 어느 User의 프로세스인지 User ID가 표시가 되어야 한다.

 

2. Processor State Information

여기서의 Information : Program Interrupt시, Control Stack에 저장하는 정보

프로그램이 실행을 하다가 인터럽트가 걸려 중단이 될 때,
자신의 현재 상태를 Control Stack에 Save & Restore 한다.
그 때, Control Stack 에 Save 한 정보들 = Processor State Information

 

→ CPU 안에 Register가 100개쯤 있다고 가정했을 때,
Register 값을 다 저장하면 100개의 정수값을 다 저장해야 한다.
그거를 Control Stack에 다 저장하고, Copy해서 여기에도 저장하고
이렇게 Copy를 반복할 이유가 없다.

⇒ 즉, Control Stack에 PCB Pointer를 저장하는 것이다.
PCB에는 Save & Restore 할 정보값이 들어 있다.

  • 정보는 Control Stack 한군데에 Pointer로 저장되어 있다.
  • Control Stack은 Main Memory(RAM)에 위치한다.

(1) User-Visible Registers
(2) Control & Status Registers

  • PC (Program Counter)
  • PSW (Program Status Word)

(3) Stack Pointers

3. Process Control Information

OS에게 가장 중요한 정보로,
OS가 프로그램을 실행시키면서 필요한 모든 관리 정보들을 Process Control Information 안에 넣어놨다.

1. Scheduling and State information

Scheduling Information

스케쥴링 정보: 프로세스의 우선순위, 우선순위를 계산하는데 필요한 여러가지 정보들

Time Sharing System : Process들을 번갈아 가면서 작업하는 것이다.
Ready Queue 는 먼저 들어간 프로세스가 먼저 나오는 큐라고 상상할 수 있지만,
실제로는 이렇게 간단하게 스케쥴링 하지 않고, 훨씬 더 복잡하게 스케쥴링을 진행한다.

  • 프로세스마다 우선순위가 존재한다.
  • 우선순위가 계산되는 방식이 시스템마다 다르다.

State Information

프로세스는 계속 상태가 바뀌는데, 현재 프로세스의 상태가 어떤 상태인지 나타내는 정보

2. Memory management

프로세스가 메모리의 어디서부터 어디까지 사용하고 있는지,
그러한 정보들이 들어있다.

3. Resource ownership and Utilization

Resource ownership

이 프로세스가 만든, 소유하고 있는 리소스들을 말한다.

프로세스가 리소스를 만드는 방법: Concurency Control(여러 프로세스들을 동시에 실행시킬 때 충돌을 막기 위해 시스템 안에서 세마포를 만들어서 활용한다)
프로세스가 자기 필요에 따라서 OS 영역에 세마포라고 하는 Resource를 만든다.
→ 누가 만든 세마포냐? = Ownership

ex) 다른 프로세스랑 통신을 하고 싶을 때, 통신용 메시지 Queue를 만들 수 있다.
이 메시지 큐도 당연히 OS 공간에 만든다.
A큐가 B, C, D 큐랑 통신하고 싶어 통신용 메시지 큐를 만들었을 때,
B, C, D도 이 큐를 이용할 수 있지만 주인은 A이다.

Utilization

Resource를 내가 어떻게 얼마나 사용했나를 전부 기록하여
OS가 모든 자원이 골고루 사용할 수 있도록 자원을 관리할 수 있게 해준다.

Resource 기록 → OS → 자원 공평하게 관리

4. Inter-process communication

메시지 큐뿐만 아니라 여러가지 파이프들을 만들어서 communication을 도와주는데,

실제로 communication은 OS가 한다.

A가 B에게 메시지를 보내고 싶을 때,
다이렉트로 A가 B에게 메시지를 보낼 수 있는 방법은 없다.
OS가 A의 메시지를 Copy하고 다시 B에게 메시지를 Copy해 주어야 한다.
(A Message → OS → B Message)

5. Process privileges

프로세스가 가진 여러가지 권한들

권한은 OS가 관리한다.
ex) 읽기, 쓰기, ...

6. Data Structuring

모든 프로세스는 굉장히 많은 Pointer를 관리해야 한다.

 


전체적인 프로세스 이미지

 

Private User Address Space (= Programs + Data)

  1. 프로세스 본인만 사용하는 공간이다.
  2. 프로그램이 compile되어 binary code가 될 때 이 코드가 메모리의 몇번지부터 몇번지인지가 붙어서 User Address Space 라는 이름이 붙게 된다.

Shared Address Space

다른 사람과 함께 사용하는 공간이다.

Process와 Process는 서로 data와 code를 공유할 수 있다.


OS가 해야하는 일들 (Kernel)

OS는 프로그램이기 때문에 OS가 관리하는 모든 것은 구조체 형태를 가져야 한다.

 

1. Process Manegement

  1. Process creation and termination
    프로세스 생성, 프로세스 종료 후 없애는 과정도 함께 관리된다.
  2. Process scheduling and dispatching
    실제로 CPU가 프로세스를 실행시킬 때는, 어떤 프로세스를 얼마나 실행시킬지 계산한다.(dispatching)
  3. Process switching
    프로세스가 바뀌는 상황
    A → OS → B
  4. Process synchronization and support for interprocess communication
    프로세스들이 혼자 작업하지 않고 관련된 프로세스들과 함께 작업을 진행한다.
    ⇒ 프로세스 동기화: 순서를 정하여 순차적으로 작업하는 것이 필요하다.
    또한 OS가 중간에서 communication을 도와주어야 한다.
  5. Management of process control blocks (PCB)

2. Memory Management

  1. Allocation of address space to processes
    할당 관리
  2. Swapping
  3. Page and segment management
    프로세스 → 메모리 자르는 단위 관리

3. I/O Management

  1. Buffer management
  2. Allocation of I/O channels and devices to processes
    프로세스들이 서로 사용하려고 할 때 누구에게 줄 지 결정하는 역할을 한다.

4. Support Functions

  • Interrupt handling
    OS가 해야하는 작업들 중 가장 중요하다.
    애플리케이션들은 OS의 도움을 받아야한다. 혼자서는 실행 X

OS가 끼어드는 상황은 딱 두가지이다.

  • 끼어들어달라고 요청(System call)
  • Interrupt
  • Accounting
    시스템 안에 있는 모든 프로세스가 자원을 어떻게 얼마나 사용하는지 기록
  • Monitoring
    시스템 전체 상황 모니터링하며, 문제가 생기면 해결한다.

Process Creation

Process를 만드는 작업

1. Assigns a unique process identifier to the new process

새로운 Process에게 제일 먼저 Identifier를 부여한다.

2. Allocates space for the process

Process를 실행하려면, 메모리 공간을 할당해주어야 한다.

3. Initializes the Process Control Block (PCB)

PCB를 만들어 준다.
프로세스가 가지고 있는 네가지 정보 중에서 프로그램 코드와 데이터는 이 프로세스 것이다.
→ 얘네들은 그냥 파일에서 읽어서 채우면 된다.

 

그런데, 스택은 실행을 하면서 채워가는 공간이다.
프로세스가 처음 만들어졌을 때 PCB를 만드는 것이 중요하다.

프로세스는 갑자기 등장하지 않는다.
부모 프로세스의 PCB를 복사하여 자식 프로세스를 만들고, 이를 업데이트 하는 방법을 사용한다.

4. Sets the appropriate linkages

새로 만들어진 프로세스는 프로세스 테이블 어딘가에 존재하고,
어느 큐에 들어가게 된다.
여기 저기 구조체에 들어가며 링크를 계속 수정(update)해야 한다.

 

새로 만들어진 프로세스를 적절히 여러 Queue , Tree , Table 에 넣고
→ 링크설정을 다 한다.

5. creates or expands ohter data structures

  1. 이 프로세스에게 필요한 초기 자원들이 있으면 자원들을 할당해 준다.
  2. 관련된 Data Structure들을 만들어준다.

Process Switching

 

Switching : 실행 중이던 프로세스 일단 중단 → OS가 다른 프로세스를 실행한다.

 


When to Switch Processes

Interrupt와 Trap은 둘 다 일종의 Interrupt이다.
1. Hardware interrupt(장치에 의한 인터럽트)
2. Software interrupt(명령에 의해 발생, Trap )

대부분 Trap 은 오류상황이나 Excption Handling 을 해야하는 상황을 나타낸다.

Interrupt

1. Clock interrupt (→ ready state)

running → timeout → ready

2. I/O interrupt (→ running state / → ready state)

Process B가 I/O 요청 → B는 Blocked로 이동 → Process C 실행
→ B의 I/O 인터럽트 → Process C의 실행중단

 

Process C의 입장에서는 본인의 Timeout이 아닌데도 계속 중단해야 하는가?
OS가 I/O를 완료한 후,

  • Ready로 이동할 수도 있고,
  • Running으로 Timeout 될때까지 계속 진행할 수도 있다.

3. Memory Fault (→ blocked state)

프로그램의 페이지만 들어가서 실행해야 한다.

실행 중, 페이지의 마지막 줄의 다음줄이 필요한데 없을 경우 하드디스크에서 가져와야 한다.
이를 Memory Fault라고 한다.
일종의 인터럽트이다.

Trap (→ exit state / → running state)

오류가 발생하거나 Exception Handling이 필요해 종료해야 하는 경우

 

대부분의 경우 종료상태로 가지만,
오류가 난 줄 알았는데 OS가 확인했을 때 오류가 아니었을 경우 다시 running state로 돌아올 수도 있다.

Supervisor call (→ blocked state)

Supervisor call = System call

 

User Program이 OS에게 Service를 요청하는 것이다.
요청 이후 OS가 개입하게 되면, 실행중이던 프로세스는 중단, Block 상태가 된다.

 

→ I/O 라이브러리에 printf, scanf와 같은 함수를 실행시켜,
WRITE와 READ와 같은 System call을 OS에게 요청하는 것


Processor Excution Mode

여기서의 Mode 는 CPU의 실행 모드를 가르킨다.

Q. User Mode와 Kernel Mode에 대하여 설명하시오.

User Mode

  1. 현재 CPU가 User Program 명령을 1줄을 실행하는 모드.
  2. 권한에 제한이 많다.

Kernel Mode = System Mode = Control Mode = Supervisor Mode

  1. 현재 CPU가 OS 프로그램 명령을 1줄 실행하는 모드.
  2. 권한에 제한이 적다.

Mode Switching vs. Process Switching

Mode Swithching

User mode A → Kernel mode (OS의 개입) → User mode A

⇒ mode 변경이 존재한다.

Process Switching = Context Switching

User mode A → Kernel mode (OS의 개입) → User mode B

⇒ mode 변경이 존재하고 Process의 변경도 존재한다.

즉, Mode Switching이 발생하더라도 Process Switching은 발생하지 않을 수 있다.

 


Process 상태 변화

 

 

1. CPU의 상태 저장

A라고 하는 프로그램이 실행하고 있었는데 중단이 되고 OS가 끼어들어야 하니까,
지금 현재 A를 실행하고 있던 CPU의 상태를 저장해놓아야 한다.

= Processor의 Context를 Save한다.

 

CPU 안에 있는 Register 값들을 저장하는 것인데, 근사한 말로 Context를 저장한다고 한다.

  • Register 값들 = Context

2. PCB 내용 업데이트

실행 중이던 Process의 PCB 값들을 Status, 프로세스가 access했던 자원 관련 정보들을 update 한다.

3. Process를 적절한 Queue로 이동

4. 다음에 실행할 Process 선택

 

5. 다음에 실행할 Process의 PCB 업데이트

(Ready 였을 것임 ← Blocked나 다른 상태에 있던 큐는 Running으로 실행시킬 수 없음)

6. 실행을 하기 위해서 필요한 Memory Data Structure Update

7. Process 상태 Restore

아까 저장해 놨었던 Context 값들 다시 CPU에 Restore
마지막에 PC Restore ⇒ 프로그램 시작


OS의 실행

I/O Interrupt
 ↳  I/O 인터럽트는 내가 I/O를 요청한 것이 아니다.

 

I/O 인터럽트가 끝나면
인터럽트 전에 실행중이던 프로세스가 OS의 계산에 의하여 Running이 유지될 수도, Ready로 이동할 수도 있다.

Non-process Kernel

  1. OS는 프로세스가 아니다.
  2. 프로세스가 아니므로 프로세스 이미지로 관리되지 않는다.
  3. 스케쥴링도 다른 방식으로, 메모리 관리도 다른 프로세스들과 다른 방식으로 관리한다.
    → 별도로 관리

⇒ Kernel 은 프로세스 바깥에서 모든 권한을 갖는 개체이다.

↳ 요즘 잘 사용하지 않는다.
초기에 OS의 크기가 작아 Kernel = OS 일 때, 사용하던 방식이다.

Execution Within User Processes

⇒ User Program 안에서 OS를 실행시키는 방식

User Program이 실행
→ 인터럽트가 걸리거나 Supervisor call이 들어왔으면
→ OS를 실행한다.

↳ 이때, OS가 별도의 프로그램으로 만들어서 실행하는 것이 아니라,
User Process 안에서 실행하는 것

Q.  프로세스 안에서 실행한다?

⇒ 프로세스의 실행이 무엇이냐?
프로세스가 실행할 때, 프로그램의 코드와 데이터(전역 변수, static 변수의 개수, 공간의 변화)는 변화가 없다.
⇒ 즉, 공간이 계속 변하는 것은 Stack 밖에 없다.
⇒ 즉, 실행은 Stack이 쌓였다가 내려갔다가 값이 바뀌는 것을 말한다.

프로세스 안에서 실행이 된다는 것은,
프로세스 안에서 Kernel이 Stack을 쌓아가면서 실행을 하는 것을 말한다.

이런 경우 OS가 작업을 하는 동안 프로세스가 변하지 않는다.

  • 만약에 Time Out이었다고 하면, 작업을 끝내면서 프로세스를 바꾼다.
  • I/O Interrupt였다고 하면, 프로세스를 바꾸지 않고, 작업을 끝내고 계속 실행을 하면 된다.

Process-Based Operating System

모든 OS 코드들을 별도의 프로세스로 관리한다.

P1 ~ Pn : 프로세스, 다시 OS1 ~ OSK : 프로세스

어떤 작업을 하든지간에, 일단 Switching 을 해야한다.
P1 실행하다 OS 작업이 시작되면 일단 P1을 다 저장해놓고 OS1을 실행한다.

이렇게 실행을 하면 일단 원래 작업하던 프로세스는 중단을 시키고 Ready 상태로 이동해야 한다.

반응형