공유 메모리를 사용해야 할 일이 생겨서 공부한 내용들을 정리.
공유 메모리는 다른 프로세스 간에 데이터를 공유하기 위한 메커니즘이라고 한다.
이를 통해 프로세스들이 동일한 메모리 영역에 접근하여 데이터를 읽고 쓸 수 있다.
공유 메모리는 효율적인 데이터 교환 방법이지만, 동시 접근 관리(예: 락, 세마포어)에 대한 고려가 필요.
이 포스팅에서는 간단한 예제만 기록.
접근 관리는 나도 잘 못하기 때문에 스터디 후 남기는 것으로..
C# 에서 MemoryMappedFile 라는 클래스를 제공한다.
이 클래스는 파일 기반 또는 파일이 아닌 메모리 기반의 메모리 맵을 생성, 열고 조작할 수 있는 메서드와 속성을 제공한다고 한다.
System.IO.MemoryMappedFiles
메모리 맵 파일의 특정 부분에 대한 접근을 제공하는 클래스이다.
이를 통해 메모리 맵의 일부분에 대한 읽기, 쓰기 작업을 수행할 수 있다.
static void Main(string[] args)
{
string shName = "TestMemoryMap";
// MemoryMappedFile.CreateNew => 새로운 메모리 맵 파일을 생성.
// 메서드 파라미터 : 맵 파일 이름, 맵 파일 크기(Byte 단위)
using (var mmf = MemoryMappedFile.CreateNew(shName, 1000))
{
// MemoryMappedViewAccessor 메모리 맵 파일의 특정 부분에 대한 접근을 제공.
// MemoryMappedViewAccessor 통해 메모리 맵의 일부분에 대한 읽기, 쓰기 작업을 가능.
using (var accessor = mmf.CreateViewAccessor(0, 100))
{
// CreateViewAccessor 특정 부분에 대한 접근자 생성.
// 파라미터 : 접근할 시작 offset, 접근할 크기
// 두 파라미터 다 Byte 단위
byte[] data = Encoding.UTF8.GetBytes("Secetion 1 Data");
accessor.WriteArray(0, data, 0, data.Length);
// WriteArray 접근자를 사용하여 공유 메모리에 쓴다.
// 파라미터 : 쓰기 시작할 offset, 쓸 데이터, 데이터의 시작 인덱스, 데이터 길이.
}
// 두 번째 섹션에 데이터 쓰기
using (var accessor = mmf.CreateViewAccessor(100, 100))
{
byte[] data = Encoding.UTF8.GetBytes("Section 2 Data");
accessor.WriteArray(0, data, 0, data.Length);
}
Console.WriteLine("Data written to different sections of shared memory.");
Console.ReadLine();
}
}
읽을 때도 MemoryMappedFile 와 MemoryMappedViewAccessor 를 사용
static void Main(string[] args)
{
string shName = "TestMemoryMap";
// 이미 생성된 공유 메모리 열기
// OpenExisting : 이미 존재하는 메모리 맵 파일을 열어야 한다.
using (var mmf = MemoryMappedFile.OpenExisting(shName))
{
// 첫 번째 섹션에서 데이터 읽기
using (var accessor = mmf.CreateViewAccessor(0, 100))
{
byte[] data = new byte[100];
accessor.ReadArray(0, data, 0, data.Length);
// ReadArray 접근자를 이용해서 공유 메모리 데이터 읽는다.
Console.WriteLine($"Data read from first section: {Encoding.UTF8.GetString(data)}");
}
// 두 번째 섹션에서 데이터 읽기
using (var accessor = mmf.CreateViewAccessor(100, 100))
{
byte[] data = new byte[100];
accessor.ReadArray(0, data, 0, data.Length);
Console.WriteLine($"Data read from second section: {Encoding.UTF8.GetString(data)}");
}
}
}
MemoryMappedFile의 OpenExisting는 Window 환경에서만 작동한다고 한다.

위 두 코드를 다른 프로젝트에서 실행시키면(쓰기 먼저 실행) 사진과 같은 결과를 확인할 수 있다.