[C#] 공유 메모리 - 1

빵욱·2024년 1월 31일

C#_SharedMemory

목록 보기
1/1

공유 메모리를 사용해야 할 일이 생겨서 공부한 내용들을 정리.

공유 메모리?

공유 메모리는 다른 프로세스 간에 데이터를 공유하기 위한 메커니즘이라고 한다.
이를 통해 프로세스들이 동일한 메모리 영역에 접근하여 데이터를 읽고 쓸 수 있다.
공유 메모리는 효율적인 데이터 교환 방법이지만, 동시 접근 관리(예: 락, 세마포어)에 대한 고려가 필요.

이 포스팅에서는 간단한 예제만 기록.
접근 관리는 나도 잘 못하기 때문에 스터디 후 남기는 것으로..

MemoryMappedFile 클래스

C# 에서 MemoryMappedFile 라는 클래스를 제공한다.
이 클래스는 파일 기반 또는 파일이 아닌 메모리 기반의 메모리 맵을 생성, 열고 조작할 수 있는 메서드와 속성을 제공한다고 한다.

System.IO.MemoryMappedFiles

MemoryMappedViewAccessor 클래스

메모리 맵 파일의 특정 부분에 대한 접근을 제공하는 클래스이다.
이를 통해 메모리 맵의 일부분에 대한 읽기, 쓰기 작업을 수행할 수 있다.

공유 메모리에 메모리 맵 파일 생성 후 쓰기 작업 예제.

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();
    }

}

공유 메모리 읽기

읽을 때도 MemoryMappedFileMemoryMappedViewAccessor 를 사용

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 환경에서만 작동한다고 한다.

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

profile
rove drink eat

0개의 댓글