[운영체제] 3. 프로세스
프로세스
프로세스의 정의
- 실행 중인 프로그램이다.
- 프로그램의 실행 흐름이다.
- 능동적인 존재다.
- 메모리나, cpu, I/O 등을 점유하는 상태를 가지는 개체
- 프로세스의 수 : 다중 프로그래밍 정도라고 볼 수 있다.
프로세스의 정말 간단한 구조
-
Text : Code
-
data : global
-
heap : 동적 할당
-
stack : 함수 실행 흐름
-
heap, stack은 서로 겹치지 않도록 해야 한다.
- 실제 C의 메모리 관리 기법입니다.
프로세스의 상태
프로세스 블록
-
execution states
-
scheduling information
-
state transition(mode bit)
-
accounting information도,,
cpu 사용 시간, 경과 시간 등
프로세스 스케줄링에 대한 간략 정보
- 준비 큐 : 언제든 실행 가능, 연결리스트로 저장.
- 대기 큐 : I/O를 기다리는 중
- 갖가지 친구들은 waiting queue 입니다.
Context Switching
-
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 파싱하고 보여주는 등등
렌더러가 따로 실행 됨으로써, 다른 렌더러의 고장에 독립적이게 되며, 보안을 위해 샌드박스안에서 실행된다.
-
플러그인 : 브라우저와 렌더러 연결,
upcall(signal 구현)
-
시그널 처리 과정
만약 타이머 인터럽트라면, 타이머 인터럽트 때
- 시그널 스택에 현재 돌고있는 프로세스의 정보들을 다 저장해준다. (PC, SP, register 등등)
- 시그널 핸들러로 점프시켜서 프로세스를 실행시킴(프로그램 카운터를 signal handler쪽으로 바꿔벌임)
- 시그널핸들러가 종료하면 다시 커널로 복귀시킴, 프로세스의 실행흐름을 리셋한다.
- 커널이 다시 일반프로세스 실행시킴
프로세스간 통신(IPC)
- 정보 공유의 측면, 계산 가속화의 측명,: 딥러닝을 생각해라..
-
공유 메모리
프로세스가 각각 해당 공유 메모리를 자신의 주소공간에 추가한다.
!!일반적으로는 안 되는 일이잖아..
-
메시지 큐 방식
운영체제가 제공한다.
오버헤드가 조금 있지만, 많지 않은 양을 사용할 때는 괜찮을 지도 모른다.
IPC중, 메시지 큐 방식에 대한 깊은 설명
- 직접 통신
- 보내는 애는 P를 직접 지정
- 받는 애는 누구한테 받을 건지에 까지 지정
- 누구에게 받을 지 까지는 아닌 것까지 가능. 이런 경우에는, ID argument에 어떤 프로세스가 넣어줬는지 하는 정보가 들어갈 수 있다.
- 간접 통신
- 메일 박스나, 포트로 메세지를 저장시키고, 가져간다.
- 받고, 보내는 방식
- blocking send
- non-blocking send
- blocking recv
- non-blocking recv
그냥, 명령 하고 나서 FAIL이 나도 다른 작업을 바로 수행할 수 있는가?에 달림.
- 용량에 따른 방식
- 무용량: 그냥, 송신자는 수신자가 가지고 갈 때 까지 기다린다.
- 유한용량 : 송신자는, 버퍼 용량이 꽉 차면 기다린다.
- 무한 용량: 송신자는,그냥 버리고 간다.
예시 - POSIX 공유 메모리
python
fd = shm_open(name, O_CREAT | O_RDWR, 0666); -> name을 적당히 주고, fd를 만들어 준다.
ftruncate(fd, 4096); -> 객체의 크기 지정
mmap -> 실제 fd를 사상시킨다.
MAP_SHARED를 통해 이거를 보는 모든 객체가 이걸 공유하도록 한다.
- 쓰는 쪽
- 읽는 쪽
MACH의 예
- port mapped mailbox를 이용한다. 수신자는 포트 하나를 점유하며, 송신자는 여러 개의 포트를 점유할 수 있다.
- 내부의 커널들이 mail box를 통해 소통한다. 부트스트랩 서버에 포트를 등록하면, 다른 테스크가 해당 포트를 부트스트랩 서버에서 확인할 수 있다.
윈도의 예
- 연결포트와 통신포트 사용(advanced local procedure call facility, ALPC)
-
제일 위에가 연결 포트, 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]은 쓰기
- fork를 통해서만 구현되기에 부모자식간에만 사용 가능
- 일반 파이프는 단방향이기에, 사용하지 않는 파이프는 닫아야 한다.
- 일반 파이프(익명파이프, 윈도우)
비슷하다.
- 지명 파이프(유닉스)
- 반이중통신(즉 양뱡향 동시는 안 되지만 양뱡향은 된다)
- FIFO파일이라고도 함
- open, read,write,close등의 파일과 같은,,
- 바이트 단위
- 지명 파이프(윈도우)
- 전이중통신
- 바이트 단위, 메시지 단위 가능
소켓
파이프는 다른 기계들 사이에서는 사용 못 했었다는 점을 인지하자.
별 거 없다. 그냥 create socket하고, socket("찍는 주소", 포트) 로 하면 된다.
빅앤디안 리틀앤디안
RPC (REMOTE PROCEDURE CALL)
-
그니까, 서버열고, 포트열고, 왔다갔다 하려고 하면 여러 기기들의 프로토콜을 동시에 맞추는 게 사실상 너무 어렵다.
-
어떤 프로세스의 프로시저를 호출할 건지, PORT를 처음에 매치메이커가 알려준다.
-
결국, 어떤 일을 하는게 조금 더 중요한 작업에서 유용하겠네.
클라이언트와 서버 사이에서 왔다 갔다 상호작용 해야 하는 경우 적합.
클라이언트가 데이터를 단순히 받고자 하는 목적이 아니고, 서로 상호작용 해야 할 때.
-
클라이언트 몰래 하는 기적
즉, 서버에서 함수가 무조건 실행되므로 동일한 코드를 어떤 디바이스에서도 동시에 실행할 수 있다.
- STUB은 어떤 추상화를 제공. apPLICATION이 일일이 데이터에 대해 무결성 검사를 할 필요가 없게끔 한다.
안드로이드의 rpc
다른 기종이 아닌 데도 rpc를 한다.
Author And Source
이 문제에 관하여([운영체제] 3. 프로세스), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@hoyeon94/운영체제-3.-프로세스저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)