본문 바로가기
🚗 Major Study (Bachelor)/🟧 Operating System

[OS / 운영 체제] Process Termination, IPC, Shared Memory Segment, Producer Consumer Problem, Message Passing Systems, System 5

by H_uuuk 2022. 3. 28.
728x90

예외처리에 대한 코드는 추가할 것.

 

More about wait

 

Process Creation in win32

CreateProcess()는 fork와 exec를 합쳐놓은 함수라고 할 수 있다.

WaitForSingleObject()는 wait function과 비슷한 역할을 한다.

ZeroMemeory()는 다음에 설명

 

Process Termination

exit() 을 하고 종료를 하게 될때 가지고 있는 모든 것을 free 하고 종료하게 된다. 그렇다면 free 안해도 되는 것인가? 아니다. 무조건 free로 deallocate를 해줘야 한다. 현실적으로 대부분의 경우 loop가 들어가기 때문에 비슷한 동작을 돌리게 되는데 Memory leak가 생기면 메모리가 조금씩 버려지게 된다. 처음 동작할 때는 정상 동작하지만 결국 죽게 된다. 이런 패턴의 경우 디버깅하기가 힘들다. 증상을 확인하기 힘들기 때문이다.  해당 프로그램에 메모리 Leak가 있는지 확인할 수 있는 방법이 있다. Task Manager를 띄우면 시간에 따른 그래프가 나온다. 전체적으로 수평인 그래프가 나오는데 프로그램 하나라도 Leak가 발생하면 조금씩 증가하게 된다. 

 

Multiprocess Architecture Chrome Browser

Browser 마다 프로세스를 처리하고, Renderer, Plug-in 이라는 프로세스도 존재한다. 프로세스는 독립적인 개체들이고 침범하지 못한다고 하는데 어떻게 가능한가?

 

IPC

모두다 kernel이 제공해주는 통신을 이용해야 한다. 프로세스 Communication 방식은 여러가지가 있다. 첫 번째 방식은 Message passing model이다. 이것은 real world의 우체국같은 것을 의미한다. A가 이 메시지를 누구한테 전달해달라고 요청을 한다. Interrupt 형식으로 요청을 하게 된다. B는 해당 메시지가 있으면 달라는 요청을 Interrupt를 통해서 하게 된다. 두 번째 방식은 Shared Memory이다. malloc은 특정 프로세스에 속하게 되지만 shared memory의 경우 같은 공간을 사용하기 때문에 Communication할 수 있다. 

 

Shared Memory Segment

빠르다. OS한테 해당 shared memory block을 만들어달라고 요청을 해야 한다. A와 B를 연결하는 Bridge 역할을 한다. 메모리를 읽는 속도가 나온다. 두 번째 장점은 Memory block을 크게 잡을 수 있기 때문에 대용량으로 소통할 수 있다. 하지만 단점으로는 동시에 사용하는 경우이다. Sync를 맞춰야 하고 그 약속을 프로세서끼리 해야 한다.

 

Producer Consumer Problem

하나는 Produce라고 불린다. 정보를 만들어서 Shared Memeory에 집어 넣는 역할을 하고 Consumer는 Shared Memory에서 Read해 가는 것이다. Producer Consumer Problem의 정의상 Producer는 쓰기만 하고 Consumer는 읽기만 한다고 가정한다. 대표적인 예로 comiler와 accessor가 있다.

 

Producer Consumer Problem

먼저 Source를 Assembly code로 바꿔주고 이를 다시 Binary code로 바꿔주는 과정을 하게 된다. 즉, 두 번의 과정을 거치게 된다. Assembler가 source code를 Assembler로 만들어서 Shared Block에 넣어주게 되고, Assembler가 다시 Binary code로 바꿔주게 된다..

 

Producer Consumer Problem

대부분의 경우 Buffer 크기에 제한이 있다. 그럼 Producer가 unbounded Buffer에서는 계속할 수 있다. Buffer의 크기는 끝이 없다는 가정으로 진행된다. 반면 Bounded Buffer Problem에서는 무한히 Buffer가 꽉 찰 때까지 진행을 하게 된다. 빈 공간이 없으면 기다려야 한다. 빈 공간은 Consumer가 만들어주게 된다. Consumer의 입장에서 Shared Memory가 비어있는 경우 접근하면 안됀다. 기다려야 하는데 Producer가 넣어줄 때까지 기다려야 한다.

 

 

Producer-Consumer Problem using Bounded Buffer

Circuler queue를 이용해서 구현한다. in과 out이 같을 때 Buffer가 비어있다고 할 수 있다. 

 

Circular Queue

 

Producer-Consumer Problem using Bounded Buffer

Producer의 경우 Buffer가 꽉 차있으면 기다려야 한다. 그렇기 때문에 while 문의 state를 실행시키게 된다. 그 이후의 줄은 Circuler Queue에 존재하는 코드이다. Consumer의 경우도 멈추지 않기 위해 while(1)이 존재하고 비어 있으면 기다리라는 문장이 반복된다. 뒤의 두 개 문장은 CirculerQueue에서 Item을 꺼내게 된다. Shared Memory에 올라갈 변수와 올라가면 안 될 변수의 기준은 무엇인가. Producer와 Consumer가 둘 다 사용하는 변수의 경우 Shared Memory에 올라가야 한다. 

 

Message Passing Systems

좋은 점은 요청만 하면 된다는 것. 대부분 kernel이 알아서 처리를 해준다. Shared Memory의 경우 Conflict가 발생할 수 있다. 이 경우 Conflict는 없다. 단점은 속도가 느리다는 것이다. 메모리의 Accesss 속도보다는 느리다. MEssage Queue의 사이즈가 제약이 있다. 큰 데이터를 보낼 때 제약이 존재한다. 장점은 다른 컴퓨터로 보낼 수 도 있다는 점이다. 

 

 

Message Passing System

kernel한테 부탁하는 방법은 System call 방식이다. 2 개의 System call이 필요하다. 첫 번째로는 Send()이고 두 번째로 receive() 이다. 실제 구현하기 위해서 여러 가지 방식이 있다. Direct / Indirect, Sync / Async 등등 존재한다.

 

Direct / Indirect Communication

나랑 대화하는 상대를 어떤 식으로 지정하는 가. Direct는 직접 프로세스로 보내게 되고 Indirect는 Mail Box로 보내고 또 받게 된다. Direct의 경우 PID를 알아야 보낼 수 있지만 Indirect의 경우 PID를 알지 못해도 보낼 수 있다. 

 

System 5

shared memory block을 만들어야 한다. 만드는 함수의 이름은 shmget이다. 이 함수를 호출하면 Process안이 아닌 공통 영역에 만들어지게 된다. address를 리턴하지 않고 int 값을 리턴한다. Address는 프로세스마다 별도의 체계를 가지고 있다. shared memory block을 접근할 때는 Address를 가지고 접근하지 못하고 OS가 unique 한 번호 하나를 반환하게 된다. shmget의 두 번째 파라미터는 size이고 이에 해당하는 크기만큼 Shared Block을 만든다. shmat 함수를 이용해서 mapping 관계를 만들어서 Process 내부의 주소를 사용하므로써 똑같이 할당할 수 있게 만들어 준다. shmat의 첫 번째 파라미터로 Shared Memory의 Return 값을 가지게 된다. 그 값이 shmat의 첫 번째 파라미터로 넘겨주게 된다. malloc이랑 동일하다. 

 

System 5

두 번째 프로세스의 경우 shmget은 호출하면 안됀다. shmget을 호출하고 fork를 하면 해당 seg_id를 child process도 이용할 수 있다. shared memory를 사용할 때 structure와 화살표를 많이 사용한다.

shmdt(), mapping을 끊어주는 역할을 한다. deallocation은 다시 해줘야 한다

 

Shared Memory

shmctl() 은 deallocation을 해주는 함수이다. attatch 할 때마다 increase 해주고 detach 할 때마다 decrease해주는 변수가 존재한다. attach 하고 있는 동안에는 마음대로 사용해도 된다. 

 

 

Reading Assignment 과제

 

POSIX Shared Memory

Memory-mapped file이라는 개념을 사용한다. POSIX의 shared memory는 file을 통해서 이루어진다. shm_open으로 열때와 open을 열때의 차이점. open은 일반 파일을 여는 것이고 shm_open은 개념적으로 file이지만 메모리 상에 존재하는 것을 여는 것이고, Access를 할 때 메모리에 접근하는 속도를 낼 수 있다는 것. 그리고 공유하기 위해서 만든 파일이라는 점이 open과 다른 점이 된다. 

ftruncate() 메모리의 사이즈를 지정하고 싶을 경우 사용하는 함수이다. 

mmap() 의 경우 리턴 타입은 주소가 된다. 주소가 리턴 값이면 읽거나 쓸 수 있다는 것을 명심.

shm_unlink() 함수는 shm_open을 만든 것을 없애주는 함수.