일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- background process
- houdini
- bg 명령어
- 추가 업로딩 중
- bash shell 조건문
- msync
- foreground process
- ps 명령어
- Standard Stream
- 개체 외곽 하이라이트 기준선 없애는 법
- bash shell 반복문
- 3D 배경 그래픽
- 섭페
- wait 시스템 콜
- substance painter
- 섭페에서 텍스처 추출
- bash shell 변수
- fork 시스템 콜
- 후디니
- copy-on-write
- exec 시스템 콜
- exit()
- mmap
- 뷰포트
- 생활코딩 복습
- Redirection
- pane & desktop
- Symmetry
- atexit()
- 3Ds max 기초
- Today
- Total
Researcher to Developer
01. 프로세스와 스케쥴러 4 본문
#컨텍스트 스위칭 개념 정리(문맥 교환)
CPU안에서 A라는 Process에서 B라는 Process로 바꿔줄 때 컨텍스트 스위칭이라고 함. 보통 어셈블리어로 작성됨!
CPU에 실행할 프로세스를 교체하는 기술이며, 컨텍스트 스위칭에 대한 코드가 존재함.
프로세스 상태 정보를 PCB로부터 CPU에 로드하고, 실행
1. 실행 중지할 프로세스 A PCB 정보를 해당 프로세스의 PCB에 업데이트해서, 메인 메모리에 저장
2. 다음 실행할 프로세스 B PCB 정보를 메인 메모리에서 로드하여 해당 PCB(PC/SP)정보를
CPU PC/SP 레지스터에 넣고, 실행
#PCB(Process Control Block)
PC(Program Counter) + SP(Stack Pointer)
PC,SP는 어디에 저장하나? PCB에 저장!
다음의 값들이 저장되어 있다.
1. Process ID
2. Register값 (PC, SP)
3, Scheduling info (Process state - ready 상태냐, block 상태냐 running 상태냐)
- 스케줄링에도 사용된다.
4. Memory info (메모리 사이즈 limit)
PCB는 프로세스의 상태를 저장하는 데이터 구조로 운영 체제에서 관리하고있다.
PCB : 프로세스가 실행 중인 상태를 캡쳐/구조화해서 저장
#PCB : 리눅스 예
#디스패치
Ready 상태의 프로세스를 running 상태로 바꾸는 것
#실제로는 굉장히 짧은 시간 (ms) 단위로 프로세스 스위칭이 일어남
컨텍스트 스위칭 시간이 오래 걸리면 일종의 오버헤드, 추가적인 공수(log)가 많으면 결과적으로
전체적인 프로세스 실행 시간도 그만큼 오래 걸린다.
스위칭는 빈번하게 일어나기 때문에 그 시간을 줄이는 것이 관건임.
→ C언어 대신에 어셈블리어로 작성된 경우가 많음
#초기 컴퓨터 프로그램들은 어셈블리어로 작성됨
- 서로 다른 CPU 아키텍처가 등장할 때 마다 매번 똑같은 프로그램 작성(이식성이 떨어짐)
- 어셈블리어로는 프로그램 작성 속도가 매우 떨어짐(속도가 빠름)
#컴파일러 등장
CPU 아키텍처에 따라서는 컴파일러 프로그램만 만들면 됨, 기존 코드는 재작성할 필요 없음(이식성이 높음)
그러나 어셈블리어로 작성한 코드보다는 속도가 떨어질 수 있음(속도가 느림)
#리눅스의 경우 컨텍스트 스위칭 코드는 각 CPU마다 별도로 존재
#IPC 기법 -프로세스간 커뮤니케이션
- 프로세스간 직접적인 커뮤니케이션하는 방법은 없다. 그럴 땐 특별한 IPC 기법을 사용한다.
프로세스들이 서로의 공간을 쉽게 접근할 수 있다면, 다른 프로세스 데이터/코드가 바뀔 수 있으니
매우 위험하다. 그래서 프로세스는 기본적으로 커뮤니케이션 할 수 없도록 제한하고 있다.
프로세스간 통신이 필요한가?
- 성능을 높이기 위해 여러 프로세스를 만들어서 동시 실행하는 경우가 존재, 이 때 프로세스간 상태 확인 및 데이터 송수신이 필요
ex.
1. fork() 시스템 콜(C언어 함수)
시스템 콜 안에서 fork() 함수를 실행하면, 동일한 프로세스를 가진 자신을 복사하여, 새로운 프로세스를
만들 수 있음.
1에서 10000까지를 더할 때 하나의 프로세스는 1부터 10000까지 일일이 세지만
fork() 함수로 10개의 프로세스를 만든 경우, 각각 1 ~ 1000, 1001 ~ 2000, ... 더해서 각각
더한 값을 모두 합하면, 더 빠르게 동작이 가능하다는 것
웹 서버
웹 서버는 요청이 오면 HTML 파일을 클라이언트에 제공하는 프로그램
새로운 사용자 요청이 올 때마다, fork()함수로 새로운 프로세스 만들고, 각 사용자 요청에 즉시 대응
CPU 병렬 처리가 가능하다면, 더 빠른 대응이 가능
단, 이 때 각 프로세스 제어 및 상태 정보 교환을 위해 프로세스간 통신이 필요
클라이언트와 서버
2. 파일을 이용
간단히 다른 프로세스에 전달한 내용을 파일에 쓰고, 다른 프로세스가 해당 파일을 읽으면 되는 구조
그러나 파일을 사용하면, 실시간으로 직접 원하는 프로세스에 데이터 전달이 어려움, 시간이 오래 걸림
왜? 해당 프로세스가 파일을 읽어야 하는데 계속 실시간으로 읽고만 있을 수는 없으니..
3. 실제 프로세스 : 리눅스 예
프로세스간 공간은 완전히 분리되어 있다.
어떤 프로세스든 지정할 수 있는 주소는 0 ~ 4GB 의 주소
3 ~ 4GB 사이는 운영체제 코드가 들어가는 곳(커널 영역)
0 ~ 3GB 사이는 프로그램이 쓰는 공간(사용자 영역)
프로세스간 커널 영역은 공유된다!
#다양한 IPC 기법
1. File 사용 - 실시간이 어려움, 시간이 많이 걸림
2. Message Queue
3. Shared Memory
4. Pipe
5. Signal
6. Semaphore
7. Socket
2번 부터는 모두 커널 공간을 사용하는 것 - 커널 공간은 공유한다는 것이 핵심
#Pipe
기본 파이프는 단방향 통신(부모 → 자식 방향만 가능하다는 의미)
파이프 코드 예제
fork() 라는 시스템 콜이 호출이 되면(함수가 실행되면)
새로운 프로세스가 생기는 데 기존 프로세스를 완전히 복사한다.
그러나 부모 프로세스는 pid에 실제 프로세스 ID가 들어가고, 자식 프로세스 pid에는 0이 들어간다.
그러므로 부모/자식 프로세스가 코드는 같을 지라도 동작을 다르게 한다.
프로세스를 넘어서 데이터를 전달했다는 것이 핵심
fd[1] write → fd[0] read
실제 데이터는 커널 영역에 존재한다.
#Message queue
큐니까, 기본은 FIFO 정책으로 데이터 전송
메세지를 넣은 순서대로 볼 수 있다.
메세지 큐 코드 예제
msqid, msgsnd, msgrcv, key
#Pipe vs Message queue
부모/자식 프로세스 only vs not
단방향 vs 양방향
둘 다 커널 공간의 메모리를 사용한다는 공통점은 있음
#공유 메모리(Shared memory)
커널에 공간을 만들어 놓고 C언어 포인터처럼 주소값을 가지고 와서 마음대로 여러
프로세스가 그 해당 공간을 쓰거나 하는 것
- 커널 영역에 메모리 공간을 만들고, 해당 공간을 변수처럼 쓰는 방식
- 메모리 큐 처럼 FIFO 방식이 아니라, 해당 메모리 주소를 마치 변수처럼 접근하는 방식
- 공유 메모리 KEY를 가지고 여러 프로세스가 접근 가능
공유 메모리 코드 예제
shmid, shmget, ket_t, size, shmaddr, shmat, strcpy((char *) shmaddr)
#프로세스간 커뮤니케이션 - IPC 기법 외 프로세스간 통신 기술
1. Signal - 이벤트
여러 가지 이벤트들을 미리 정했다.
운영 체제 단에서 정의 했음
주요 시그널
SIGKILL 프로세스를 끝내라(슈퍼관리자가 사용하는 시그널로, 프로세스는 어떤 경우는 끝나도록 되어있음)
SIGALARM 알람을 발생한다
SIGSTP 프로세스를 멈춰라(Ctrl + z)
SIGCONT 멈춰진 프로세스를 실행해라
SIGINT 프로세스에 인터럽트를 보내서 프로세스를 끝내라
SIGSEGV 프로세스가 다른 메모리영역에 침범했다.
SIGUSR1 → 기본동작 X → 특별 동작
SIGUSR2 → 기본동작 X → 특별 동작
두 가지 프로세스 간의 SIGUSR1, 2 를 서로 통신하면서 특별한 동작을 하게끔함
시그널 관련 코드 예제
signal, SIGINT, signal_handler
유닉스에서 30년 이상 사용된 전통적인 기법
커널 또는 프로세스에서 다른 프로세스에 어떤 이벤트가 발생되었는지를 알려주는 기법
프로세스 관련 코드에 관련 시그널 핸들러를 등록해서, 해당 시그널 처리 실행
1) 시그널 무시를 한다던지
2) 시그널 블록, 일정시간 동안 기본동작을 하지 않게 한다던지(블록을 푸는 순간, 프로세스에 해당 시그널 전달)
3) 등록된 시그널 핸들러로 특정 동작 수행을 한다던지
4) 등록된 시그널 핸들러가 없다면, 커널에서 기본 동작 수행을 한다던지
#시그널과 프로세스
PCB에 해당 프로세스가 블록 또는 처리해야하는 시그널 관련 정보 관리
Sigpending 받은 시그널이 있다는 자료구조
pending 처리 대기 중인 시그널을 표현
blocked 블럭된 시그널 표현
sig 각각의 시그널에 대해서 어떤 동작을 해야할지를 정해주는 구조
시그널은 커널모드에서 사용자모드로 넘어갈 때 항상 체크를 해서 시그널을 처리한다.
2. Socket
소켓은 네트워크 통신을 위한 기술, 네트워크 기기를 이용할 수 있는 시스템 콜
기본적으로는 클라이언트와 서버 등 2개의 다른 컴퓨터간의 네트워크 기반 통신을 위한 기술
소켓을 하나의 컴퓨터 안에서, 2개의 프로세스간에 통신 기법으로 사용 가능
#프로세스 총 정리 및 프로그램 성능 개선 방법의 이해
프로그램을 짜면 → 컴파일 → 실행 파일 → 실행 파일을 실행하려면 쉘 인터페이스를 사용 (CLI/GUI)
→ 운영 체제에 실행파일을 실행해달라고 요청 → 실행 파일 구조가 만들어지고
→ 프로세스가 Ready 상태에 들어가고 스케쥴러가 Running state로 바꿔주고 → 컨텍스트 스위칭 해주고
프로그램을 짤 때 가장 필요한 것은 빈번한 IO 처리를 최소화 하는 것.
'빅데이터'의 Spark
'코딩 > Basic' 카테고리의 다른 글
05. 가상 메모리의 이해 (0) | 2020.12.20 |
---|---|
04. Thread의 이해 (0) | 2020.12.18 |
01. 프로세스와 스케쥴러 3 (0) | 2020.12.13 |
01. 프로세스와 스케쥴러 2 (0) | 2020.12.10 |
01. 프로세스와 스케쥴러 1 (0) | 2020.12.10 |