이 페이지에서

네이티브 IPC 키

QSharedMemory 및 QSystemSemaphore 클래스는 "키"라고 알려진 시스템 전체에 적용되는 식별자를 사용하여 자원을 식별합니다. 저수준 키 값과 키 유형은 Qt에서 QNativeIpcKey 클래스를 통해 캡슐화됩니다. 이 클래스는 또한 QNativeIpcKey::toString() 및 QNativeIpcKey::fromString() 메서드를 통해 다른 프로세스와 키를 교환할 수 있는 적절한 수단을 제공합니다.

Qt는 현재 이 두 클래스에 대해 QNativeIpcKey::Type 열거형에 정의된 값들과 일치하는 세 가지 서로 다른 백엔드를 지원합니다.

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

이름에서 알 수 있듯이, Windows 프리미티브는 Windows 운영 체제에서만 사용할 수 있으며, 해당 운영 체제에서는 기본 백엔드로 설정됩니다. 나머지 두 가지는 일반적으로 Unix 운영 체제에서 모두 사용할 수 있습니다. 다음 표는 Qt 6.6 이후의 일반적인 지원 현황을 요약한 것입니다:

운영 체제POSIXSystem VWindows
Android
INTEGRITY
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에 대해서는 아래를 참조하십시오). 이 형식은 일반적으로 크로스 플랫폼이 아니므로, QSharedMemory 와 QSystemSemaphore 모두 크로스 플랫폼 식별자 문자열을 네이티브 키로 변환하는 함수인 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 App Store를 통해 배포되는 모든 애플리케이션에는 샌드박스가 적용됩니다. 애플리케이션의 그룹 식별자를 얻는 방법을 포함한 자세한 내용은 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/Open 시스템 인터페이스(XSI) / System V

System V 키는 시스템 내 파일 이름의 형식을 따르므로, 파일 경로와 똑같은 제한 사항이 적용됩니다. QSharedMemory 와 QSystemSemaphore 는 모두 객체를 생성할 때 해당 파일이 존재하지 않으면 이 파일을 생성합니다. 자동 제거가 비활성화된 경우, QSharedMemory 와 QSystemSemaphore 간에 충돌 없이 공유될 수 있으며, 존재하는 어떤 파일이라도 사용할 수 있습니다(예를 들어, 프로세스 실행 파일 자체일 수 있음. 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 이전에는 QNX를 제외하고 Qt가 POSIX 실시간 객체를 정리한 적이 없었습니다.

X/Open 시스템 인터페이스(XSI) / System V

Qt 클래스가 관리하는 리소스는 두 가지가 있습니다: 키가 참조하는 파일과 객체 자체입니다. ` QSharedMemory `는 객체를 협력적으로 관리합니다. 즉, 마지막 연결이 객체 자체를 제거한 다음 키 파일을 제거할 책임이 있습니다. ` QSystemSemaphore `는 ` QSystemSemaphore::Create`가 전달된 경우에만 객체를 제거하며, 또한 키 파일을 생성한 경우 해당 파일도 제거합니다.

Qt 6.6부터는 두 클래스 모두에 대해 정리 작업을 수행하지 않도록 요청할 수 있습니다.

Windows

운영 체제가 객체를 소유하며, 객체에 대한 마지막 핸들이 닫히면 정리합니다.

기존 Qt 애플리케이션과의 상호 운용성

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

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

QSharedMemory 와 QSystemSemaphore 의 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/Open 시스템 인터페이스(XSI) / System V

QSharedMemory 키에 기존 파일을 절대 사용하지 마십시오. 구형 Qt 애플리케이션이 해당 파일을 삭제하려고 시도할 수 있기 때문입니다. 대신 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비트로 변환하거나 8비트에서 원래 이름으로 변환할 수 있습니다.

X/Open 시스템 인터페이스(XSI) / System V

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

이 두 함수 중 하나에 전달되는 key 매개변수는 QNativeIpcKey::nativeKey()에서 얻은 파일 이름에 id 로 81 또는 0x51(ASCII 대문자 'Q')을 지정하여 ftok() 함수를 호출했을 때의 결과입니다.

System V 세마포어 객체에는 여러 개의 세마포어가 포함될 수 있지만, QSystemSemaphore 는 첫 번째 세마포어( sem_num 의 경우 번호 0)만 사용합니다.

QSharedMemory 와 QSystemSemaphore 는 모두 마지막 연결인 경우, 각각 shmctl() 및 semctl() 로 IPC_RMID 작업을 사용하여 객체를 제거하도록 기본 설정되어 있습니다.

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