for and exec 함께 사용하지 않은 이유
- fork와 exec을 분리시켜 새 프로그램을 실행하기 전 다양한 설정과 IO redirection과 pipe를 가능하게 하려고
프로세스 실행
- OS가 프로그램 실행을 시작하려면
- process list에 새로운 항목을 생성한다. 이후 메모리 페이지 할당. 디스크에있는 프로그램 실행파일을 메모리페이지에 로드. 진입점으로 포인터를 위치한다.
문제점
- 프로세스가 원치 않는 일을 하지 않는다는 보장할 수 있는가?
- 프로세스 실행 시 OS가 이를 중단시키고 다르 프로세스를 실행시킬수 있는가?(time sharing)
OS가 실행 프로그램 제어못하면 OS가아니라 라이브러리
문제1 : 제한된 연산
- 프로세스가 특수한 형태의 연산을 수행시키려면 ? IO, 메모리 접근
- 프로세스에게 별도의 제한 없이 특수한 형태의 연산 수행을 허용한다.
- 파일 시스템 접근 권한 문제가 발생한다.
- 이런 문제로 User mode Kernel 모드가 나뉘게 되었다.
- 유저모드 - 권한을 덜 가진 사용자모드. 사용자프로그램들이 일반적으로 이모드에서 수행
- 응용프로그램은 하드웨어 리소스에 완전히 접근 가능
- 커널 모드 - 시스템의 모든 리소스에 접근 가능
- 기본적으로 프로세스는 유저모드이며 연산에따라 커널모드로 전환되었다가 다시 유저모드로 복구된다.
- 프로그램의 현재상태를 저장하는 PSW bit가 있는데 이를통해 프로세스의 모드가 어떤 타입인지 알 수 있다
- 프로세스에게 별도의 제한 없이 특수한 형태의 연산 수행을 허용한다.
인터럽트
- 현재 수행중인 프로세스와는 독립적으로 외부에서 유발되는 여러 종류의 사건(ex 입출력 완료)에 의해 발생
- 프로세스가 유저모드에서 커널모드로 변경되도록함
- HW INTERRUPT
- 외부에서 유발되는 사건에 의해 비동기적으로 발생하는 인터럽트. I/O, TIME QUNTUM
- SW INTERRUPT
- TRAP, SYSTEM CALL이 있다.
- 클럭 인터럽트, 입출력 인터럽트, 메모리 폴트
트랩
- 불법 파일접근시도처럼, 현재 수행되고있는 프로세스에서 생성되는 오류,예외조건 때문에 발생
- 현재 process의 명령어를 수행하는 도중 error나 exception이 발생해 이에 대한 처리를 하는 비동기적 호출이다.
HW INTERRUPT /TRAP처리 (거의 시스템콜, 예외처리 처리)
- 여러 HW에서 인터럽트 정보를 수집하고 인터럽트 발생시 CPU에 신호를 전달한다.
- CPU는 커널의 인터럽트 테이블에서 해당 인터럽트 ENTRY POINTER값을 찾는다.
- 이때 모드가 유저모드에서 커널모드로 바뀐다.
- 찾은 포인터값은 인터럽트 핸들러 내부 특정함수를 가리키고 처리가 수행된다.
시스템콜 처리 과정
- C코드에서 FORK 함수는 어셈블리어 MOVL, INT 명령어로 변환된다.
- 이중 INT 명령어는 INTERRUPT 명령어 이다.
- 이를 통해 인터럽트 테이블을 찾아간다. 시스템콜도 인터럽트라 인터럽트 테이블에 ENTRY가 차지하고있다.
- 이 포인터값을 이용해 찾아간 인터럽트 핸들러는 시스템콜주소들을 저장하는 SYSCALL테이블을 갖고있는데 해당 테이블 내부에서 SYS_FORK에 대한 주소를 찾은뒤 시스템콜 핸들러가 SYS_FORK명령을 실행하도록 명령한다.
시스템콜 추가
- syscall table에 새로운 함수 등록
- 함수 header syscalls.h에 추가
- 함수 body가 작성된 C source code file 작성
- C source code file을 컴파일 해 Object file(.o) 생성 후 kernel 경로에 저장
문제2 : 프로세스간 전환
- 협조적 접근 방법
- 프로세스가 yield 시스템콜 호출해서 os에게 제어를 넘기고 os가 다음 프로세스 선택
- 너무 수동적이라 yield 호출 못하게 된다면?
- 비협조적 접근방법
- 프로세스가 yield 호출 거부하거나 호출되지 않을경우 hw의 도움 없이 os가 할 수 있는 일은 없음
- time interrupt 이용 → 현재 수행중인 프로세스 중단→인터럽트핸들러수행→os가 제어권가짐
- 현재 실행 중이던 process의 context를 저장
- 현재 실행 중이던 process의 PCB를 갱신 (상태를 Ready, Block, Sleep, Zombie 등으로 변경)
- PCB를 os의 schedule 정책에 따른 특정 queue로 이동
- os의 schedule 정책에 따라 다음 process를 선택
- 선택된 process의 PCB를 갱신 (상태를 Running으로 전환)
- 선택된 process가 이전 수행에서 사용했던 context를 복원
모드 전환 프로세스 교환
- 모드 전환은 커널모드 유저모드 사이 전환이다. 현재 실행중인 프로세스 상태를 바꾸지 않고 가능하다.
- 프로세스 전환은 실제 문맥을 따로 저장및 교환해야하므로 많은 연산을 필요로한다.
- exit() → schedule() → switch() : 문맥교환 zombie 상태
- I/O → schedule() → switch() : 문맥교환 block 상태
- clock interrupt → schedule() → switch() : 문맥교환 runnable (또는 memory가 부족할 경우 suspend) 상태
병행성 문제
- 인터럽트 트랩을 처리하는 중에 다르 인터럽트가 발생하면
- 기본적으로 대부분 os 는 중첩 인터럽트를 금지한다. 그사이 발생한 새로운 인터럽트에 대해 처리하지 않는다.
'Operating System' 카테고리의 다른 글
[Operating System] 공평한 스케줄러 (0) | 2022.12.28 |
---|---|
[Operating System] MLFQ Multi-level Feedback Queue Scheduling (2) | 2022.12.28 |
[Operating System] 스케줄링 (0) | 2022.12.19 |
[Operating System] 프로세스 (0) | 2022.12.19 |
[Operating System] 운영체제란? (0) | 2022.12.19 |