사실은 스레드의 접근은 이 내용을 읽다 보면 그래서 스레드 쓰는구나 할 수도 있어서 과감하게 제외했습니다.
사실 공유 메모리를 사용해 프로세스가 접근하는 것과 스레드가 공유 자원에 접근하는 것은 맥락은 비슷하다고 느껴진다. 그래서 이 둘의 차이가 분명히 존재하지 않을까? 해서 찾아본 내용입니다.
공유 메모리(Shared Memory)는 가장 빠른 IPC 매커니즘으로 평가를 받습니다. 왜냐하면, 공유메모리는 데이터를 프로세스들 간에 전달할 때 운영체제 커널을 통한 데이터 복사하지 않고 사용자 공간에서 바로 데이터를 읽고 쓰게 설계되었기 때문입니다. 다른 프로세스끼리 통신을 하기 위해선 무조건 Kernel 메모리 공간에 데이터를 보내고 다른 프로세스가 Kernel 메모리 공간에 접근해 데이터를 읽어와야 하는 구조였습니다. 예를 들어 Pipe 또는 Message Queue(Kernel Buffer를 이용한).
하지만 공유 메모리는 하나의 공유 메모리 공간을 만들어 놓고 모든 프로세스가 접근 가능하게끔 만들었기때문에 충분히 User 메모리 공간에서 데이터 전달이 가능해졌죠.
하지만, 공유 메모리에 접근한다는 것은 문제가 하나 발생하게 되는데요. 동시에 접근하게 되면 데이터의 일관성이 깨져 원하는 결과를 얻지 못하는 상황이 발생하는 것입니다. 그래서 동기화(Synchronization)를 하게 됩니다. 이때 프로세스는 독립적인 메모리 공간을 갖고 있기 때문에, 설정이 더 복잡하고 동기화에 부담이 갈 수밖에 없습니다. 왜냐하면 모든 프로세스마다 메모리 설정을 따로 진행해주어야 하기 때문입니다.
다들 아시겠지만, 프로세스는 메모리를 할당받을 때 독립된 메모리를 할당받게 됩니다. 이로 인해서 프로세스들끼리는 자신들의 영역에 다른 프로세스가 침범하지 못하게 만들 수 있는 이점을 가져다 주었습니다.
어쨌든, 공유 메모리도 프로세스가 다른 메모리를 참조하는 것이기 때문에 운영체제 커널을 통해 특별하게 메모리를 매핑해주어야합니다. 접근 가능한 메모리를 매핑해 주는 것이죠, 그래서 System Call을 사용해야만 하죠. (POSIX 표준에선 shmget, shmat, shmdt와 같은 API를 제공합니다.)
위와 같은 API를 사용해서 물리 메모리와 직접적인 연결을 보장해야하며, 이를 위해 페이지 테이블을 수정해야 합니다. 모든 프로세스가 동일한 물리 메모리를 참조하도록 매핑을 일관되게 관리해야 하죠. 이러한 과정은 추가적인 설정과 시스템 자원 관리를 요구하게 됩니다.
매핑(Mapping) 과정
어떤 이유 때문에 매핑이 어려워지는 걸까요? 매핑의 과정에 대해서 살펴보겠습니다.
각 프로세스는 자신의 주소 공간과 물리 메모리를 매핑하기 위한 페이지 테이블(Page table)을 가지고 있습니다. 서로 다른 프로세스의 주소 공간은 독립적이므로, 한 프로세스의 주소 공간에서 공유 메모리의 물리 주소를 참조하려면 운영체제가 별도의 설정을 통해 공용 물리 메모리 영역을 양쪽에 매핑을 하게 됩니다.
운영체제는 동일한 물리 메모리 페이지를 여러 프로세스의 서로 다른 가상 주소에 매핑해야 하므로, 페이지 테이블을 수정하고 일관성을 유지해야 합니다.
공유 메모리 설정 과정
1. 공유 메모리 영역 생성
공유 메모리를 생성하기 위해 한 프로세스는 System Call을 사용해 커널에 요청을 전달합니다. 한 프로세스가 다른 프로세스들과 공유 메모리안에서 데이터를 공유하기 위해선, 무조건 한 프로세스는 공유 메모리 영역을 생성해야합니다.
2. 커널의 요청 검사
검사가 완료되었다면 적절한 크기의 물리 메모리 페이지를 할당합니다.
3. 공유 메모리 매핑(Mapping)
프로세스가 공유 메모리에 접근하면, 커널이 해당 프로세스의 가상 주소 공간에 공유 메모리를 매핑합니다.
shmat 호출을 통해 작업이 수행됩니다. 그리고 해당 프로세스의 페이지 테이블에 공유 메모리의 물리 주소와 가상 주소를 매핑합니다. 이 작업은 각 프로세스 고유한 주소 공간에서 별도로 이루어지게 됩니다. 그래서 프로세스마다 페이지 테이블을 수정해야 합니다.
페이지 테이블 수정은 너무나도 복잡합니다. (커널에서 이루어지기 때문에 복잡하다는 표현을 넣었습니다.)
각 프로세스의 페이지 테이블은 독립적으로 존재(프로세스마다 페이지 테이블을 갖고 있기 때문에)합니다. 모든 관련 프로세스의 페이지 테이블을 수정해야하는데, 이는 커널 모드 전환을 요구하며 추가적인 CPU 비용을 초래합니다. 동일한 물리 메모리가 여러 프로세스에 매핑되기 때문에, 매핑 정보가 서로 충돌하지 않도록 관리까지 이뤄져야 합니다.
TLB(Translation Lookaside Buffer) 동기화도 해야합니다. CPU 캐시에는 페이지 테이블의 최근 항목이 저장된 TLB라는 구조가 있습니다. 공유 메모리와 같은 새로운 매핑이 발생하면 TLB의 내용을 무효화(Invalidate)하고 갱신해야 합니다.
틀린 내용
- 공유 메모리 접근과 커널의 관여 여부
- "공유 메모리는 운영체제 커널을 전혀 거치지 않는다"는 뉘앙스는 부정확합니다.
- 공유 메모리 설정(생성, 매핑 등)과 접근 권한 관리는 커널 모드에서 이루어지며, 시스템 호출을 통해 수행됩니다. 다만 데이터 읽기/쓰기는 커널 개입 없이 사용자 공간에서 직접 수행됩니다.
- 정확한 설명: 초기 설정과 매핑은 커널 모드에서 수행되지만, 이후의 데이터 읽기/쓰기 작업은 커널 개입 없이 이루어짐.
- "공유 메모리는 운영체제 커널을 전혀 거치지 않는다"는 뉘앙스는 부정확합니다.
- "페이지 테이블 수정이 매우 복잡하다"
- 페이지 테이블 수정은 커널에서 자동으로 처리되는 작업으로, 애플리케이션 관점에서 "복잡하다"는 표현은 적절하지 않습니다. 이는 커널 수준에서 처리되며, 프로세스 간 매핑 충돌 방지나 TLB 무효화는 운영체제가 관리합니다.
애매한 내용
- 프로세스 간의 독립적 메모리 공간 비교
- 공유 메모리는 독립적인 프로세스 메모리 공간을 초월해 데이터를 주고받는 구조를 갖습니다.
- 반면, 스레드는 동일한 프로세스 내에서 메모리를 공유합니다. 그러나 프로세스 간 공유 메모리가 커널의 추가 설정이 필요하다는 점과 스레드가 동일한 메모리를 암묵적으로 공유한다는 점의 차이를 좀 더 명확히 설명해야 합니다.
- TLB 동기화 오버헤드의 실질적 영향
- TLB 무효화로 인한 성능 저하가 중요할 수 있지만, 실제로는 시스템 구조와 프로세스 수에 따라 이 오버헤드가 큰 영향을 미치지 않을 수도 있습니다. 더 구체적인 사례 연구가 필요합니다.
추가로 알아봐야 할 것들
- 스레드와 공유 메모리 비교
- 스레드는 공유 자원에 암묵적으로 접근할 수 있지만, 공유 메모리는 명시적인 설정 과정(System Call)이 필요합니다. 이러한 차이가 실제로 성능이나 복잡성에 어떤 영향을 미치는지 분석이 필요합니다.
- TLB 무효화 비용 분석
- TLB 무효화의 실질적인 오버헤드가 다양한 시스템 구조에서 얼마나 중요한지에 대한 수치적 데이터가 필요합니다.
- Intel 및 AMD 문서에서 제공하는 캐시 일관성과 TLB 관리 연구를 참고할 수 있습니다.
- POSIX API와 System V API 비교
- 공유 메모리 구현에 사용되는 POSIX와 System V API 간의 차이점을 추가로 연구해야 합니다. 이는 설정의 복잡성과 동기화 방식에도 영향을 미칠 수 있습니다.
Summary
- 공유 메모리 특징
- 프로세스 간 데이터를 빠르게 공유하며, 사용자 공간에서 직접 읽기/쓰기 작업이 이루어짐.
- 커널을 통해 설정(System Call) 및 매핑 작업이 필요하며, 페이지 테이블과 TLB 동기화 작업이 동반됨.
- 동기화 메커니즘(세마포어, 뮤텍스 등)을 통해 데이터 일관성을 유지해야 함.
- 스레드의 접근 방식
- 동일 프로세스 내에서 자원을 공유하므로 별도의 매핑 작업이 필요하지 않음.
- 그러나 공유 메모리와 마찬가지로 동기화 문제 발생 가능.
- 스레드는 커널 개입 없이 간단한 동기화 메커니즘(뮤텍스, 조건 변수 등)만으로도 자원 접근을 조율할 수 있음.
- 주요 차이점
- 설정의 복잡성: 공유 메모리는 커널 모드 전환과 페이지 테이블 수정 작업이 필요, 스레드는 설정 없이 접근 가능.
- 오버헤드: 공유 메모리는 초기 설정에서 커널 개입으로 인한 오버헤드 발생. 스레드는 간단한 동기화 작업 외에 추가 비용이 적음.
- 사용 사례: 공유 메모리는 독립적인 프로세스 간 통신에 적합, 스레드는 동일 프로세스 내 병렬 작업에서 효과적.
'CS > 운영체제' 카테고리의 다른 글
Run 중에 Interrupt가 된다면? (1) | 2024.11.29 |
---|---|
Process가 생성되면서 PCB(Process Control Block)이 어떻게 변화할까? (0) | 2024.11.26 |
프로세스간 통신 IPC(Inter Process Communication) (0) | 2024.11.25 |
Running중이고, Kernel mode로 전환되면서 Waiting으로 상태가 변경된다면? (1) | 2024.11.24 |
프로세스가 Ready Queue에서 선택되어서 Running 상태가 되었을때 (0) | 2024.11.24 |