네이티브 IPC 키

QSharedMemoryQSystemSemaphore 클래스는 "키"로 알려진 시스템 전체 식별자를 사용하여 리소스를 식별합니다. 저수준 키 값과 키 유형은 QNativeIpcKey 클래스를 사용하여 Qt로 캡슐화됩니다. 이 클래스는 QNativeIpcKey::toString() 및 QNativeIpcKey::fromString()을 통해 다른 프로세스와 키를 교환하는 적절한 수단도 제공합니다.

Qt는 현재 이 두 클래스에 대해 QNativeIpcKey::Type 열거형에서 사용할 수 있는 값과 일치하는 세 가지 백엔드를 지원합니다.

  • POSIX 실시간 확장(IEEE 1003.1b, POSIX.1b)
  • X/오픈 시스템 인터페이스(XSI) 또는 시스템 V(SVr4), 현재 POSIX의 일부이기도 합니다.
  • Windows 프리미티브

이름에서 알 수 있듯이 Windows 프리미티브는 기본 백엔드인 Windows 운영 체제에서만 사용할 수 있습니다. 나머지 두 개는 일반적으로 유닉스 운영 체제에서 모두 사용할 수 있습니다. 다음 표는 Qt 6.6 이후의 일반적인 가용성에 대한 개요를 제공합니다:

운영 체제POSIX시스템 VWindows
Android
무결성
QNX
macOS보통(1)
기타 Apple OS
기타 유닉스 시스템
Windows드물게(2)

참고: 1 Apple App Store를 통해 배포된 모든 애플리케이션을 포함하는 샌드박스가 적용된 macOS 애플리케이션은 System V 객체를 사용하지 못할 수 있습니다.

참고: 2 Windows의 일부 GCC 호환 C 런타임은 POSIX 호환 공유 메모리 지원을 제공하지만, 이는 드문 경우입니다. Microsoft 컴파일러에는 항상 이 기능이 없습니다.

특정 키 유형이 지원되는지 확인하려면 응용 프로그램에서 QSharedMemory::isKeyTypeSupported() 및 QSystemSemaphore::isKeyTypeSupported()를 호출해야 합니다.

QNativeIpcKey 는 또한 도입 이전의 Qt 응용 프로그램과의 호환성을 지원합니다. 다음 섹션에서는 백엔드의 제한 사항, 문자열 키 자체의 내용 및 호환성에 대해 자세히 설명합니다.

크로스 플랫폼 안전 키 형식

QNativeIpcKey::setNativeKey() 및 QNativeIpcKey::nativeKey()는 낮은 수준의 네이티브 키를 처리하며, 이 키는 네이티브 API와 함께 사용되거나 다른 비 Qt 프로세스와 공유될 수 있습니다(아래에서 API를 참조하세요). 이 형식은 일반적으로 크로스 플랫폼이 아니므로 QSharedMemoryQSystemSemaphore 모두 크로스 플랫폼 식별자 문자열을 네이티브 키로 변환하는 함수를 제공합니다: QSharedMemory::platformSafeKey() 및 QSystemSemaphore::platformSafeKey().

대부분의 플랫폼에서 크로스 플랫폼 키의 길이는 파일 이름과 동일하지만, Apple 플랫폼에서는 사용 가능한 바이트가 30바이트로 엄격하게 제한됩니다(US-ASCII 범위를 벗어난 문자를 사용하는 경우 UTF-8 인코딩에 유의하세요). 키의 형식도 파일 경로 구성 요소의 형식과 유사하므로 Apple 운영 체제의 샌드박스 애플리케이션을 제외하고는 파일 이름에 허용되지 않는 문자, 특히 경로 구성 요소를 구분하는 문자(슬래시 및 백슬래시)를 포함하지 않아야 합니다. 다음은 크로스 플랫폼 키의 좋은 예입니다: "myapp", "org.example.myapp", "org.example.myapp-12345". 키가 너무 커지는 것을 방지하고 해당 플랫폼에서 키에 유효한 문자가 포함되어 있는지 확인하는 것은 호출자의 책임입니다. Qt는 너무 긴 키는 자동으로 잘라냅니다.

Apple 샌드박스 제한: 애플리케이션이 Apple 운영 체제의 샌드박스 내부에서 실행되는 경우 키는 매우 특정한 형식이어야 합니다: <application group identifier>/<custom identifier>. 샌드박스는 Apple 앱 스토어를 통해 배포되는 모든 애플리케이션에 대해 암시적으로 적용됩니다. 애플리케이션의 그룹 식별자를 얻는 방법을 비롯한 자세한 내용은 여기와 여기 Apple 설명서를 참조하세요.

네이티브 키 형식

이 섹션에서는 지원되는 백엔드의 기본 키 형식에 대해 자세히 설명합니다.

POSIX 실시간

기본 키는 파일 이름과 유사하며 슬래시를 제외한 파일 이름과 같은 모든 문자를 포함할 수 있습니다. POSIX에서는 키 이름의 첫 번째 문자는 슬래시여야 하며 추가 슬래시가 허용되는지 여부는 결정되지 않은 상태로 둡니다. 대부분의 운영 체제에서 키 길이는 파일 이름과 동일하지만 Apple 운영 체제에서는 32자로 제한됩니다(여기에는 첫 번째 슬래시와 종료 널이 포함되므로 사용 가능한 문자는 30자만 가능).

다음은 기본 POSIX 키의 좋은 예입니다: "/myapp", "/org.example.myapp", "/org.example.myapp-12345".

QSharedMemory::platformSafeKey() 및 QSystemSemaphore::platformSafeKey()는 슬래시 앞에 슬래시를 추가하기만 하면 됩니다. Apple 운영 체제에서는 결과를 사용 가능한 크기로 잘라내기도 합니다.

Windows

Windows 키 유형은 NT 커널 객체 이름이며 최대 MAX_PATH (260자)까지 가능합니다. 상대 경로처럼 보이지만(즉, 백슬래시나 드라이브 문자로 시작하지 않음) Windows의 파일 이름과 달리 대소문자를 구분합니다.

다음은 기본 Windows 키의 좋은 예입니다: "myapp", "org.example.myapp", "org.example.myapp-12345".

QSharedMemory::platformSafeKey() 및 QSystemSemaphore::platformSafeKey()는 각각 공유 메모리와 시스템 세마포어를 구분하기 위해 접두사를 삽입합니다.

X/오픈 시스템 인터페이스(XSI)/시스템 V

시스템 V 키는 시스템 내 파일 이름의 형태를 취하므로 파일 경로와 똑같은 제한이 있습니다. QSharedMemoryQSystemSemaphore 모두 객체를 만들 때 이 파일이 존재하지 않으면 이 파일을 만듭니다. 자동 제거가 비활성화되어 있는 경우 QSharedMemoryQSystemSemaphore 간에 충돌 없이 공유될 수 있으며 존재하는 모든 파일이 될 수 있습니다(예: 프로세스 실행 파일 자체일 수 있음, QCoreApplication::applicationFilePath() 참조). 현재 디렉터리가 달라서 실수하지 않도록 경로는 절대 경로여야 합니다.

QSharedMemory::platformSafeKey() 및 QSystemSemaphore::platformSafeKey()는 항상 절대 경로를 반환합니다. 입력이 이미 절대 경로인 경우 변경되지 않은 상태로 반환합니다. 그렇지 않으면 애플리케이션이 일반적으로 파일을 만들 수 있는 권한이 있는 적절한 경로를 앞에 붙입니다.

소유권

공유 메모리와 시스템 세마포어 객체는 사용하기 전에 생성해야 하는데, 이는 각각 QSharedMemory::create() 또는 QSystemSemaphore::Create 을 생성자에 전달하여 수행합니다.

유닉스 시스템에서는 해당 객체를 생성한 Qt 클래스가 해당 객체를 정리할 책임이 있습니다. 따라서 해당 C++ 객체가 있는 애플리케이션이 깨끗하지 않게 종료되면(크래시, qFatal() 등) 객체가 남아있을 수 있습니다. 이 경우 애플리케이션은 해당 객체를 다시 만들지 못하고 기존 객체에 연결해야 합니다. 예를 들어 QSharedMemory:

if (!shm.create(4096) && shm.error() == QSharedMemory::AlreadyExists)
    shm.attach();

QSystemSemaphore 에 다시 연결하는 것은 토큰 카운터가 알 수 없는 상태일 수 있으므로 교착 상태가 발생할 수 있으므로 현명하지 않습니다.

POSIX 실시간

POSIX 리얼타임 객체 소유권은 파일을 사용하는 프로세스의 존재 여부와 관계없이 독립적으로 존재한다는 점에서 파일과 유사합니다. Qt는 객체가 아직 사용 중인지 확인할 수 없으므로 자동 제거 기능은 이 경우에도 객체를 제거하므로 동일한 객체에 대한 첨부가 불가능하지만 기존 첨부 파일에는 영향을 미치지 않습니다.

Qt 6.6 이전에는 Qt가 POSIX 실시간 객체를 정리하지 않았지만, QNX에서는 예외였습니다.

X/오픈 시스템 인터페이스(XSI)/시스템 V

Qt 클래스가 관리하는 자원은 키가 참조하는 파일과 객체 자체의 두 가지입니다. QSharedMemory 는 객체를 협력적으로 관리합니다: 마지막 첨부 파일은 객체 자체를 제거한 다음 키 파일을 제거합니다. QSystemSemaphoreQSystemSemaphore::Create 로 전달된 경우에만 객체를 제거하고, 키 파일을 생성했다면 그것도 제거합니다.

Qt 6.6부터는 어느 클래스든 정리하지 않도록 요청할 수 있습니다.

Windows

운영 체제가 객체를 소유하고 객체에 대한 마지막 핸들이 닫힌 후 정리를 수행합니다.

이전 Qt 응용 프로그램과의 상호 운용성

QNativeIpcKey 클래스는 Qt 6.6에 도입되었습니다. 이 버전 이전에는 QSharedMemoryQSystemSemaphore 백엔드가 Qt의 자체 빌드 시점에 결정되었습니다. 윈도우 시스템의 경우, 항상 윈도우 백엔드가 사용되었습니다. 유닉스 시스템의 경우, 구성 스크립트에서 사용 가능하다고 판단되면 기본적으로 System V 백엔드로 설정되었습니다. 사용할 수 없는 경우 POSIX 백엔드로 돌아갔습니다. POSIX 백엔드는 Qt 구성 스크립트에 -feature-ipc_posix 옵션을 사용하여 명시적으로 선택할 수 있으며, 활성화된 경우 QT_POSIX_IPC 매크로가 정의됩니다.

Qt 6.6에서는 구성 스크립트 옵션이 유지되지만 더 이상 백엔드의 가용성을 제어하지 않습니다. 대신 QNativeIpcKey::legacyDefaultTypeForOs()가 반환하는 내용이 변경됩니다. 호환성을 유지해야 하는 애플리케이션은 상호 운용성을 보장하기 위해 이 키 유형만 사용해야 합니다.

QSharedMemoryQSystemSemaphore 의 API에는 크로스 플랫폼 키라는 개념이 있었지만, 이제 더 이상 사용되지 않고 QSharedMemory::legacyNativeKey() 및 QSystemSemaphore::legacyNativeKey()를 사용합니다. 이 두 함수는 이전 버전에서 더 이상 사용되지 않는 함수와 동일한 네이티브 키를 생성합니다. 예를 들어 이전 코드가 다음과 같았다면

QSharedMemory shm("org.example.myapplication");
QSystemSemaphore sem("org.example.myapplication");

로 업데이트할 수 있습니다:

QSharedMemory shm(QSharedMemory::legacyNativeKey("org.example.myapplication"));
QSystemSemaphore sem(QSystemSemaphore::legacyNativeKey("org.example.myapplication"));

두 애플리케이션이 네이티브 키를 교환했다면 다음과 같은 코드를 업데이트할 필요가 없습니다:

QSharedMemory shm;
shm.setNativeKey(key);

하지만 이전 애플리케이션이 기본 키를 사용했다면 새 애플리케이션은 QNativeIpcKey::legacyDefaultTypeForOs()의 두 번째 인수와 함께 platformSafeKey() 를 사용하도록 선택할 수 있습니다.

X/오픈 시스템 인터페이스(XSI)/시스템 V

이전 Qt 애플리케이션이 제거를 시도할 수 있으므로 QSharedMemory 키에 기존 파일을 사용하지 마세요. 대신 QSharedMemory 에서 생성하도록 하세요.

Qt가 아닌 애플리케이션과의 상호 운용성

Qt가 아닌 애플리케이션과의 상호 운용성은 가능하지만 몇 가지 제한 사항이 있습니다:

  • 공유 메모리 세그먼트 생성이 경합하지 않아야 합니다.
  • QSharedMemory 세그먼트 잠금을 지원하지 않습니다.

Qt가 아닌 애플리케이션과의 통신은 항상 네이티브 키를 통해 이루어져야 합니다.

QSharedMemory 는 항상 전체 세그먼트를 메모리에 매핑합니다. Qt가 아닌 응용 프로그램은 부작용 없이 일부만 메모리에 매핑하도록 선택할 수 있습니다.

POSIX 실시간

POSIX 공유 메모리는 shm_open()을 사용하여 열 수 있고 POSIX 시스템 세마포어는 sem_open()을 사용하여 열 수 있습니다.

이 두 함수 모두 QNativeIpcKey::nativeKey()의 결과인 name 매개 변수를 받아 QFile::encodeName() / QFile::decodeName()를 사용하여 파일 이름으로 인코딩합니다.

Windows

Windows 공유 메모리 객체는 CreateFileMappingW를 사용하여 열 수 있으며, Windows 시스템 세마포어 객체는 CreateSemaphoreW를 사용하여 열 수 있습니다. 두 함수의 이름이 모두 "Create"로 시작하지만 기존 객체에 연결할 수 있습니다.

이러한 함수에 대한 lpName 매개변수는 변환 없이 QNativeIpcKey::nativeKey()의 결과입니다.

외부 애플리케이션에서 이러한 함수의 유니코드가 아닌 버전("A"로 끝나는)을 사용하는 경우 QString 을 사용하여 이름을 8비트로 변환할 수 있습니다.

X/오픈 시스템 인터페이스(XSI)/시스템 V

시스템 V 공유 메모리는 shmget()을 사용하여 얻을 수 있고 시스템 V 시스템 세마포어는 semget()을 사용하여 얻을 수 있습니다.

이러한 함수의 key 매개변수는 QNativeIpcKey::nativeKey()에서 얻은 파일 이름을 id 81 또는 0x51(ASCII 대문자 'Q')과 함께 전달할 때 ftok() 함수의 결과입니다.

시스템 V 세마포어 객체는 여러 세마포어를 포함할 수 있지만 QSystemSemaphore 는 첫 번째 세마포어만 사용합니다( sem_num 의 경우 숫자 0).

QSharedMemoryQSystemSemaphore 모두 기본적으로 마지막 첨부 파일인 경우 IPC_RMID 연산을 사용하여 객체를 각각 shmctl()semctl() 로 제거합니다.

© 2025 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.