Text : Code
data : global
heap : 동적 할당
stack : 함수 실행 흐름
heap, stack은 서로 겹치지 않도록 해야 한다.
execution states
scheduling information
state transition(mode bit)
accounting information도,,
cpu 사용 시간, 경과 시간 등
PCB에다가 이전 상태를 저장하고, 새로운 프로세스의 정보를 PCB에서 가져와서 cpu에 적재한다.
문맥교환시간은 순수한 오버헤드가 된다.
Detail
현재 가리키는 주소(cpu의 current PCB 포인터)의 프로세스 상태, return address 등을 PCB에 저장해놓는다.
이 때, 하드웨어에서 자동으로 실행하게끔 하는게 좋다.
ISR시작한다.
해당 ISR은 dispatcher 일 것이다.
register의 값을 PCB에 저장한다.
current PCB 포인터 값을 갱신한다.
새로운 PCB에 안에 있는 새로운 레지스터를 적재한다.
실행해야할 instruction의 값을 pcb에서 뽑아온다.
새로운 프로세스를 시작할 땐, 이러한 PCB가 없기 때문에, FAKE STACK을 사용할 수 있다. 그냥 기존 프로세스를 복사하거나, 더미값을 채워넣거나,,
IOS
안드로이드의 application은 백그라운드 서비스를 이용한다.
즉, 모바일에서는 application이 당장 실행 안 되어도, 음악 재생 같은게 백그라운드 서비스를 통해 자연스레 실행되도록 할 수 있다.
확장적으로 생각하면, 이렇게 단계를 나눠서 전원관리도 할 수 있겠네.
이렇게, 부모가 있는 트리 형태
fork() system call의 결과가 아닐까.
systemMD가 부팅 시작 때 처음으로 시작되어, 다른 프로세스들이 이 systemMD로부터 시작된다.
SystemMD를 추적하면 프로세스 트리를 얻을 수 있다.
프로세스 생성 시
Load data/code(복사만 해라)
create stack /heap→ 프로세스마다 다르므로, runtime시 생성한다.(당연히 부모꺼 복사해서 처음엔 만들겠지)
PCB를 만든다.
ready list에 프로세스를 넣는다.
실제 wrapping code는 다음과 같다.
python
start(arg1, arg2) {
main(arg1, arg2); // Call program main. exit(); // If main returns, call exit.
}
오버헤드 줄이기 위해, C/O/W를 이용하겠지.
처음에는 PCB의 내용을 포인팅만 하고, EXEC시 비로소 만들기.
파일 공유가 쉽다.
부모프로세스가 열고 있는 파일은 / 변수는 동일하게 자식에서 이용 가능하다.
윈도우에서는,,
그냥 프로세스를 만든다.
엄청 많은 인자를 쓴다.
프로세스의 마지막에 exit system call
kill, terminateprocess(window)등을 통해서
부모가 삭제될 때, cascade를 강제하는 경우.
좀비 프로세스
자식 프로세스가 종료되었는데,
→부모 프로세스의 확인을 기다리는 상태
→부모가 아직 wait를 호출하지 않은 상태
고아 프로세스
→말 그대로 고아, 그냥 init(systemMD) 프로세스에 붙인다.
→때에 따라서 꼭 systemMD가 아니여도 붙을 수는 있다.
하나의 application이라도 망가지면 웹 브라우저가 멈추지 않기 위함
브라우저 : 디스크, 네트워크 입출력
렌더러 : 탭마다 열리는, html 파싱하고 보여주는 등등
렌더러가 따로 실행 됨으로써, 다른 렌더러의 고장에 독립적이게 되며, 보안을 위해 샌드박스안에서 실행된다.
플러그인 : 브라우저와 렌더러 연결,
시그널 처리 과정
만약 타이머 인터럽트라면, 타이머 인터럽트 때
공유 메모리
프로세스가 각각 해당 공유 메모리를 자신의 주소공간에 추가한다.
!!일반적으로는 안 되는 일이잖아..
메시지 큐 방식
운영체제가 제공한다.
오버헤드가 조금 있지만, 많지 않은 양을 사용할 때는 괜찮을 지도 모른다.
그냥, 명령 하고 나서 FAIL이 나도 다른 작업을 바로 수행할 수 있는가?에 달림.
python
fd = shm_open(name, O_CREAT | O_RDWR, 0666); -> name을 적당히 주고, fd를 만들어 준다.
ftruncate(fd, 4096); -> 객체의 크기 지정
mmap -> 실제 fd를 사상시킨다.
MAP_SHARED를 통해 이거를 보는 모든 객체가 이걸 공유하도록 한다.
제일 위에가 연결 포트, client 가 연결 요청을 하면
서버는 핸들러를 통해 채널을 만들고
client와 server는 해당 포트를 나눈다. 그리고 통신한다.
작은 메시지는, 포트의 메시지큐 사용
대용량 메시지는 색션객체 사용, 그냥 공유메모리를 사용한다.
초 대용량은 직접 접근하는 방식을 사용한다.
응용프로그래머는 이걸 하지는 않음. 단지 운영체제에 이걸 대신 해달라고 요청한다.
ls > tmp → ls stdout > tmp
zork < solution → zork stdin < solution
ls | grep HH 라는 거는 ls의 stdout이, grep 이라는 거의 stdin이 된다
pipe(fd[]) -> fd에다가 descriptor 생성, fd[0]는 읽기, [1]은 쓰기
비슷하다.
파이프는 다른 기계들 사이에서는 사용 못 했었다는 점을 인지하자.
별 거 없다. 그냥 create socket하고, socket("찍는 주소", 포트) 로 하면 된다.
그니까, 서버열고, 포트열고, 왔다갔다 하려고 하면 여러 기기들의 프로토콜을 동시에 맞추는 게 사실상 너무 어렵다.
어떤 프로세스의 프로시저를 호출할 건지, PORT를 처음에 매치메이커가 알려준다.
결국, 어떤 일을 하는게 조금 더 중요한 작업에서 유용하겠네.
클라이언트와 서버 사이에서 왔다 갔다 상호작용 해야 하는 경우 적합.
클라이언트가 데이터를 단순히 받고자 하는 목적이 아니고, 서로 상호작용 해야 할 때.
클라이언트 몰래 하는 기적
즉, 서버에서 함수가 무조건 실행되므로 동일한 코드를 어떤 디바이스에서도 동시에 실행할 수 있다.
다른 기종이 아닌 데도 rpc를 한다.