공유 메모리
Qt는 동일한 시스템 내의 다른 프로세스와 메모리를 공유하기 위해 두 가지 기법을 제공합니다: 메모리 매핑( QSharedMemory )과 메모리 매핑 파일( QFile). 다른 프로세스와 공유되는 메모리는 흔히 "세그먼트"라고 불리며, 과거에는 세그먼트화된 메모리 모델을 사용하는 프로세서에서 특정 세그먼트로 구현되기도 했지만, 현대의 운영 체제에서는 더 이상 그렇지 않습니다. 공유 메모리 세그먼트는 단순히 운영 체제가 참여하는 모든 프로세스가 사용할 수 있도록 보장하는 메모리 영역입니다.
참고: 메모리 내에서 세그먼트가 위치한주소는 공유에 참여하는 각 프로세스마다 거의 항상 다릅니다. 따라서 애플리케이션은 C++ 기본 유형이나 해당 유형의 배열과 같이 위치에 독립적인 데이터만 공유하도록 주의해야 합니다.
QSharedMemory를 사용한 메모리 공유
QSharedMemory 는 지정된 크기의 공유 메모리 세그먼트를 생성하거나 다른 프로세스가 생성한 세그먼트에 연결할 수 있는 간단한 API를 제공합니다. 또한, 내부 ` QSystemSemaphore`를 사용하여 전체 세그먼트에 ` lock ` 및 ` unlock `를 적용하는 두 가지 메서드를 제공합니다.
공유 메모리 세그먼트와 시스템 세마포어는 “키(key)”를 통해 시스템 내에서 전역적으로 식별되며, Qt에서는 이 키가 QNativeIpcKey 클래스로 표현됩니다. 또한 OS에 따라 Qt는 메모리 공유를 위한 여러 가지 백엔드를 지원할 수 있습니다. 자세한 정보와 제한 사항에 대해서는 네이티브 IPC 키(Native IPC Keys ) 문서를 참조하십시오.
QSharedMemory 는 동일한 권한 수준 내에서만 메모리를 공유하도록 설계되었습니다(즉, 다른 사용자가 시작한 프로세스와 같이 신뢰할 수 없는 다른 프로세스와는 공유되지 않습니다). 이를 지원하는 백엔드의 경우, QSharedMemory 는 동일한 권한 수준을 가진 프로세스만 연결할 수 있도록 세그먼트를 생성합니다.
메모리 매핑 파일을 통한 메모리 공유
대부분의 파일은 ` QFile::map()`를 사용하여 메모리에 매핑할 수 있으며, ` MapPrivateOption ` 옵션이 지정되지 않은 경우 매핑된 세그먼트에 대한 모든 쓰기 작업은 동일한 파일을 매핑한 다른 모든 프로세스에서 감지됩니다. 메모리에 매핑할 수 없는 파일의 예외로는 네트워크 공유에 있는 원격 파일이나 특정 파일 시스템에 위치한 파일 등이 있습니다. 운영 체제가 원격 파일을 메모리에 매핑하는 것을 허용하더라도, 해당 파일에 대한 I/O 작업은 캐시되어 지연될 가능성이 높으므로 진정한 메모리 공유는 불가능합니다.
이 솔루션의 주요 장점은 어떤 백엔드 API에도 독립적이며, Qt가 아닌 애플리케이션과의 상호 운용이 더 간단하다는 점입니다. ` QTemporaryFile `는 ` QFile`이므로, 애플리케이션은 해당 클래스를 사용하여 정리 세манти크를 구현하고 고유한 공유 메모리 세그먼트를 생성할 수도 있습니다.
공유 메모리 세그먼트의 잠금을 구현하려면 애플리케이션이 자체적인 메커니즘을 적용해야 합니다. 한 가지 방법은 ` QLockFile`를 사용하는 것입니다. 또 다른, 비용 부담이 덜한 해결책은 세그먼트 자체의 미리 정해진 오프셋 위치에 ` QAtomicInteger ` 또는 ` std::atomic `를 사용하는 것입니다. 일부 운영 체제에서는 더 고수준의 잠금 프리미티브를 사용할 수 있습니다. 예를 들어, 리눅스에서는 애플리케이션이 ` pthread_mutex_create() `에 전달되는 뮤텍스 속성에서 "pshared" 플래그를 설정하여 해당 뮤텍스가 공유 메모리 세그먼트에 상주함을 나타낼 수 있습니다.
운영 체제는 공유 메모리에 수행된 모든 쓰기 작업을 영구 저장소에 커밋하려고 시도할 가능성이 높다는 점에 유의하십시오. 이는 의도된 동작일 수도 있지만, 파일 자체가 임시로 사용될 예정이었다면 성능 저하로 이어질 수 있습니다. 이 경우, 애플리케이션은 리눅스의 tmpfs 와 같은 RAM 기반 파일 시스템( QStorageInfo::fileSystemType() 참조)을 사용하거나, 네이티브 파일 열기 함수에 플래그를 전달하여 OS가 내용을 저장 장치에 커밋하지 않도록 지시해야 합니다.
신뢰할 수 없는 프로세스와 통신하기 위해 파일 기반 공유 메모리를 사용할 수 있지만, 이 경우 애플리케이션은 각별한 주의를 기울여야 합니다. 파일이 잘리거나 크기가 줄어들 수 있으며, 이로 인해 파일 크기 이상의 메모리에 접근하는 애플리케이션이 충돌할 수 있습니다.
메모리 매핑된 파일에 대한 리눅스 팁
최신 리눅스 시스템에서 /tmp 디렉터리는 종종 tmpfs 마운트 포인트이지만, 이는 필수 조건은 아닙니다. 반면, /dev/shm 디렉터리는 tmpfs 이어야 하며, 메모리 공유를 목적으로 특별히 마련된 것입니다. 이 디렉터리는 누구나 읽고 쓸 수 있으므로( /tmp 및 /var/tmp 참조), 애플리케이션은 여기에 노출되는 내용에 주의해야 합니다. 또 다른 대안으로는 XDG 런타임 디렉터리를 사용하는 것입니다( QStandardPaths::writableLocation() 및 QStandardPaths::RuntimeLocation 참조). systemd를 사용하는 리눅스 시스템에서 이 디렉터리는 사용자별 tmpfs 로 설정됩니다.
더욱 안전한 해결책은 memfd_create(2) 를 사용하여 "memfd"를 생성하고, QDBusUnixFileDescriptor 와 같이 프로세스 간 통신을 통해 파일 디스크립터를 전달하거나, QProcess 의 자식 프로세스가 이를 상속받도록 하는 것입니다. "memfd"는 크기가 축소되는 것을 방지하도록 봉인할 수 있으므로, 서로 다른 권한 수준을 가진 프로세스와 통신할 때 안전하게 사용할 수 있습니다.
FreeBSD의 메모리 매핑된 파일에 대한 참고 사항
FreeBSD에도 memfd_create(2) 가 있으며, 리눅스와 동일한 기법을 사용하여 다른 프로세스에 파일 설명자를 전달할 수 있습니다. 기본적으로 마운트된 임시 파일 시스템은 없습니다.
메모리 매핑된 파일에 대한 Windows 관련 참고 사항
Windows에서 애플리케이션은 운영 체제에 파일 내용을 영구 저장소에 저장하지 않도록 요청할 수 있습니다. 이 요청은 Win32 함수 ` CreateFile `의 ` dwFlagsAndAttributes ` 매개변수에 ` FILE_ATTRIBUTE_TEMPORARY ` 플래그를 전달하거나, 저수준 함수 ` _open() `에 ` _O_SHORT_LIVED ` 플래그를 전달하거나, C 런타임 함수 ` fopen() `에 수정자 "T"를 포함시켜 수행됩니다.
또한 파일에 대한 마지막 핸들이 닫힐 때 운영 체제가 파일을 삭제하도록 지시하는 플래그도 있습니다(FILE_FLAG_DELETE_ON_CLOSE, _O_TEMPORARY 및 "D" 수정자). 단, 파일을 열려는 모든 프로세스가 이 플래그를 사용할지 여부를 일치시켜야 한다는 점에 유의하십시오. 일치하지 않을 경우 공유 위반이 발생하여 파일 열기에 실패할 가능성이 높습니다.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.