KOCW.이화여자대학교.반효경.운영체제
위 강의를 바탕으로 학습 및 정리했습니다
1
프로세스의 개념
프로세스의 상태
-
CPU 한개 밖에 없음 -> CPU에서 기계어를 실행하고 있는 프로세스는 매 순간 하나
-
상태 종류 3가지
- Running 상태 : CPU를 기계어를 실행하고 있는 상태
- Ready : CPU를 쓰기 위해 대기하고 있는 상태
- Blocked/Wait/Sleep
- CPU를 줘도 실행할 수 없는 상태
- Process 자신이 요청한 event(Ex. I/O)가 아직 만족되지 않아서 이를 기다리는 상태 (Ex. DISK에서 파일을 읽어와야 하는 경우)
-
운영체제는 PCB를 통해 각 프로세스가 어떤 상태인지 일일이 다 관리함 (자료구조 큐를 활용해 관리)
-
I/O 작업이 필요하면 I/O(상태) 큐에 넣고
-> 작업이 끝나면 Ready(상태) 큐에 넣고
-> 차례가 되면 Running 상태가 됨
-
오래걸리는 작업은 하드웨어 작업 때문만이 아니다
- 공유데이터가 있는 경우
- 공유데이터 : 프로세스들이 같이 쓰는 데이터
- 공유데이터를 동시에 여러 프로세스들이 같이 쓰면 문제가 발생할 수 있음
-> 한 프로세스가 공유데이터를 사용하는 작업이 끝나면 다른 프로세스가 씀
이 경우도 Blocked 상태
프로세스 상태도
-
프로세스 상태 변화도
-
프로그램이 실행전과 종료 후는 프로세스가 아님
-
New : 프로세스가 생성 중인 상태 (본격적인 상태에 못들어온 경우)
-
Terminated : 종료될 때 뒤처리가 조금 남은 상태
-
Ready 상태는 CPU만주면 바로 실행됨
그러려면 CPU에게 당장 필요한 부분은 메모리에 올라가 있어야함
-> 따라서 그 프로세스가 메모리에 존재
-
Running이 끝나는 경우(CPU를 내놓는 경우) 3가지
- 할당시간이 만료될 경우 (Timer interrupt)
- 기계어 실행을 하다 오래걸리는 작업 수행(I/O)이 필요한 경우
- 종료될 때
PCB
문맥 교환 (Context Switch)
- CPU를 한 프로세스에서 다른 프로세스로 넘겨주는 과정
- CPU가 다른 프로세스에게 넘어 갈 때 운영체제는 다음을 수행
- CPU를 내어주는 프로세스의 상태를 그 프로세스의 PCB에 저장
- CPU를 새롭게 얻는 프로세스의 상태를 PCB에서 읽어옴
근데 문맥교환이 아닌게 있음
- 아닌경우
- 문맥교환은 사용자 프로세스A에서 사용자 프로세스B로 넘어가는 것을 의미
- A가 실행되다가 커널이 실행된 후 다시 A가 실행되는 건 문맥 교환이 아님
- 맞는 경우
- 결과적으로 사용자프로그램 A에서 다른 사용자 프로그램으로 넘어갔을 때가 문맥교환임
- (1)도 context의 일부를 PCB에 저장해야 하지만 문맥교환 하는 경우보다는 overhead가 대단히 작음
- (1)은 모든 context를 PCB에 저장할 필요는 없기 때문
- (2)의 경우 모든 cash메모리를 다 저장해야하기 때문에 빡쎄다
프로세스를 스케줄링하기 위한 큐
job queue
Readu q
Device q
- I/O device의 처리를 기다리는 프로세스가 들어감
프로세스 스케줄링 큐의 모습
- fork : 프로세스가 자식 프로세스를 만드는 행위
2
스케줄러(scheduler)
-
Time sharing system에는 보통 장기 스케줄러가 없음 (무조건 ready 상태로 들어감)
- Time sharing system
시분할 시스템(Time Sharing System)은 여러 명의 사용자가 사용하는 시스템에서 컴퓨터가 사용자들의 프로그램을 번갈아가며 처리해줌으로써 각 사용자에게 독립된 컴퓨터를 사용하는 느낌을 주는 것으로, 라운드 로빈(Round Robin)방식이라고도 한다.
- 요즘 대부분의 시스템이 시분할 시스템
-> 요즘 운영체제느 장기스케줄러를 채택하고 있지 않다
-
Short-term scheduler 단기 스케줄러 (CPU scheduler)
- CPU를 어떤 프로세스에게 얼마나 줄지 결정하는
-> CPU는 굉장히 빨리 프로세스에서 넘어가기 때문에 short-term 스케줄러는 굉장히 자주 호출됨 (timer interrupt 걸릴 때마다)
-
Medium-Term Scheduler 중기 스케줄러 (Swapper)
-
Time Sharing system에서는 장기 스케줄러가 없고 프로그램을 실행시키면 바로 ready 상태로 들어가는데 1000개를 실행 시키면 1000개가 다 메모리 올라감? 그럼 메모리 너무 비효율적인거 아님?
-> 장기 스케줄러 대신에 메모리 관리를 위해 두는 것이 중기 스케줄러 aka. Swapper
-
memory가 너무 부족할 때(효율과 성능이 너무 구릴 때) 공간을 마련하기 위해 프로세스를 통째로 메모리에서 디스크로 쫒아냄
-
어떤 프로세스를 memory를 뺄지 결정하는 (<-> 장기 프로세스는 어떤 프로세스에서 memory를 줄지 결정)
-
중기 스케줄러가 들어가면서 추가되는 프로세스 상태가 바로 Suspended(메모리에서 쫒겨난 상태, 물론 중기 스케줄러만 만들수 있는 상태는 아니고 또 다른 외부적인 요인들이 있다.)
- Blocked 상태는 I/O를 하는 등 프로세스가 여전히 일을 하고 있다, 또한 자신이 요청한 event가 만족되면 Ready로 돌아온다
- Suspended는 Blocked와 다르게 CPU도 못쓰고 아무일도 못함, 또한 외부에서 반드시 resume해줘야만 Active될 수 있다
3
프로세스 상태도
-
위 그림이 가장 적합한 프로세스 상태도
-
I/O 작업 등의 event를 수행중이던 Blocked 상태의 프로세스가 Suspended 상태가 됐을 때 event 계속 할 수 있음, 그 event가 끝나면 Suspended Ready가 됨
-
Running 상태를 2개로 쪼갬
- User mode
- Monitor mode (커널모드)
- 프로세스 자신이 할수 없는 일을 위해 시스템 콜을 해서 운영체제 코드가 실행 중 일 때
- CPU를 운영체제에게 빼았겼다 라는 개념보다 여전히 프로세스가 CPU를 쓰고 있다고 치는 것이 더 타당 (위 그림처럼 자신이 요청한 커널모드는 프로세스 A가 여전히 running하고 있다 간주하는 것)
-
Running, Ready, Blocked == Active 상태
-
Suspended == inactive 상태
- 물론 모든 suspended가 완전히 일을 안하는 상태는 아님
4
Process
- 프로세스 문맥을 의미하는 그림
- 동일한 프로그램을 여러개 실행 시켰을 때 하나하나 다 프로세스를 만드는 것과 각각이 메모리에 올라가고 PCB생기는 것은 매우 비효율적
-> Thread 를 둠
Thread
-
동일한 프로그램을 여러개 띄워도 프로세스(코드, 데이터, 스택) 하나 생성
-
대신 여러개띄워놓은 것들은 각각 다른 부분의 코드를 실행 시킬 수도 있으므로 그것만 따로 관리
(현재 CPU가 어디를 실행 시키고 있는 가와 관련된 정보만 따로 관리)
- Program counter, registers(코드의 어느 부분을 실행하고 있는가)에 해당하는 값만 Thread로 각각 나타냄
- 이런것들 외에는 하나만 생성
-
웹브라우저 여러개 띄우면 프로세스 여러개 생성
-> Thread로 효율적이게 만듬
-> Chrome의 경우 보안상의 문제가 있기도 했음
-> 이처럼 소프트웨어마다 다름
- 공유하는 부분을 Task라고 부름
- 다중 Thread에서는 하나의 Thread가 I/O작업이든 다른 작업을 위해 Blocked가 됐을 때에도 Task내의 다른 Thread가 running상태가 되어 빠른 처리 가능
Thread 장점
- Responsiveness(응답성이 빠르다)
- Resource Sharing(자원 공유)
- CPU 수행과 관련된 것들을 공유하니까
- Economy
- 프로세스하나를 만드는 것에 비해 Thread하나를 만드는 게 더 이득
- Solaris의 경우 30배 이득
- Utilization of MP Architectures (병렬성)
- 멀티쓰레드에서 여러개의 쓰레드가 병렬적으로 작업을 수행
Implementation of Thread
- 커널 쓰레드
- 유저 쓰레드 (운영체제 커널이 쓰레드 활용을 직접 지원해줌)
- 운영체제 입장에선 쓰레드가 없다고 생각하게끔 쓰레드가 설계됨 (사용자 프로그램 단에서 쓰레드 활용)
5
프로세스 생성
- 부모 프로세스가 자식 프로세스 생성
- 자식 프로세스를 만들어 달라는 시스템 콜 == fork
- 프로세스의 트리 형성
- 프로세스는 자원을 필요로함
- 자원의 공유
- 부모와 자식이 모든 자원을 공유하는 모델
- 일부를 공유하는 모델
- 전혀 공유하지 않는 모델
- 수행
- 부모와 자식이 공존하며 수행되는 모델 (경쟁하는 관계)
- 자식이 종료될 때까지 부모가 기다리는(Blocked상태) 모델
- 주소공간
- 자식이 부모의 공간을 복사
- 자식은 그 공간에 새로운 프로그램을 올림
- 예(unix)
fork()
시스템 콜이 새로운 프로세스 생성
exec()
시스템 콜을 통해 새로운 프로그램을 메모리에 올림 (새로운 프로그램을 덮어 씌우는 )
fork() 시스템 콜
- 자식을 하나 만들어달라고 하는 시스템 콜
- 복제 생성 -> 별개의 프로세스처럼 됨
- program counter 까지 복제 -> 자식도 부모가 수행하고 있는 부분부터 수행함
- 근데 누가 부모고 자식임?
- return pid (부모 : pid > 0 / 자식 : pid == 0)
프로세스 종료
- 프로세스가 마지막 명령을 수행한 후 운영체제에게 이를 알려줌(exit)
- 자식이 부모에게 output를 보냄 (
via wait
)
- 프로세스의 각종 자원들이 운영체제에게 반납됨
- 부모 프로세스가 자식의 수행을 종료시킴 (
abort
)
- 자식이 할당 자원의 한계치를 넘어섬
- 자식에게 할당된 task가 더이상 필요없을 때
- 부모가 종료될 때
exec() 시스템 콜
1. fork() 로 복제 생성
2. 자식이면 exec() 실행되서 다른 프로그램으로 덮어 씌워지고 exec() 에서 지정한 프로그램 실행
3. exec()에서 지정한 프로그램 실행(1)이 끝나면 그 아래 코드인 (2)를 실행하는게 아니고 지금 이 프로세스(자식)는 걍 끝남
프로세스와 관련한 시스템 콜
wait() 시스템 콜
- 자식을 만들어 놓고 나서 자식이 끝날 때까지 부모가 blocked(wait) 상태가 되는 시스템 콜
exit() 시스템 콜
프로세스 간 협력
- 보통 프로세스는 서로 cpu, 메모리 경쟁을 하지 협력하진 않음
- 그리고 서로의 메모리를 보지 못함
- 경우에 따라서 협력이 필요할 때가 있음. 근데 위의 두가지 특징이 있는데 어캐함?
- 협력 메커니즘
- 프로세스 간 메세지 전달
- 커널을 통해 메세지 전달 == Message passing
- 프로세스간 주소 공간 공유
Message Passing
- P에서 Q로 메세지 보냄
- 커널을 통해서 한다
- Direct Communication
- Indirect Communication
- 누가받아 볼지 명시하지 않고 보내두면 누군가가 열어봄
Shared memory
- 공유하는 것도 시스템 콜을 통해 운영체제에게 부탁함
- 공유하는 프로세스가 신뢰할 수 있는 프로세스인가에 대한 문제가 발생함
+ Thread
- 협력 방법은 아니지만 비슷함
- Thread 만들어지는 거 자체가 메모리 공간을 공유하는 것임