本页内容

QSystemSemaphore Class

QSystemSemaphore 类提供了一个通用的计数系统信号量。更多内容...

头文件: #include <QSystemSemaphore>
CMake: find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core

公共类型

enum AccessMode { Open, Create }
enum SystemSemaphoreError { NoError, PermissionDenied, KeyError, AlreadyExists, NotFound, …, UnknownError }

公共函数

QSystemSemaphore(const QNativeIpcKey &key, int initialValue = 0, QSystemSemaphore::AccessMode mode = Open)
QSystemSemaphore(const QString &key, int initialValue = 0, QSystemSemaphore::AccessMode mode = Open)
~QSystemSemaphore()
bool acquire()
QSystemSemaphore::SystemSemaphoreError error() const
QString errorString() const
QString key() const
QNativeIpcKey nativeIpcKey() const
bool release(int n = 1)
void setKey(const QString &key, int initialValue = 0, QSystemSemaphore::AccessMode mode = Open)
void setNativeKey(const QNativeIpcKey &key, int initialValue = 0, QSystemSemaphore::AccessMode mode = Open)

详细描述

系统信号量是QSemaphore 的泛化形式。通常,信号量用于保护一定数量的相同资源。

与其更轻量级的对应类一样,QSystemSemaphore 可以从多个threads 进行访问。与QSemaphore 不同的是,QSystemSemaphore 还可以从多个processes 进行访问。这意味着 QSystemSemaphore 是一个更“笨重”的类,因此如果您的应用程序不需要跨多个进程访问信号量,您可能更希望使用QSemaphore 。

信号量支持两种基本操作:acquire() 和release():

acquire() 尝试获取一个资源。如果没有可用资源,该调用将阻塞,直到有资源可用为止。随后资源被获取,调用返回。

release() 释放一个资源,以便其他进程可以获取该资源。该函数也可以带参数 n > 1 调用,此时将释放 n 个资源。

系统信号量通过键进行标识,该键由QNativeIpcKey 表示。可通过使用platformSafeKey()以跨平台方式创建键。 当向 QSystemSemaphore 构造函数传递访问模式参数AccessMode::Create 时,将创建一个系统信号量。创建完成后,其他进程可以使用相同的键和访问模式参数AccessMode::Open 连接到同一个信号量。

示例:创建系统信号量

QSystemSemaphore sem(QSystemSemaphore::platformSafeKey("market"), 3, QSystemSemaphore::Create);
                             // resources available == 3
sem.acquire();               // resources available == 2
sem.acquire();               // resources available == 1
sem.acquire();               // resources available == 0
sem.release();               // resources available == 1
sem.release(2);              // resources available == 3

有关密钥类型、特定于平台的限制以及与旧版或非 Qt 应用程序的互操作性的详细信息,请参阅《本机进程间通信密钥》文档。其中包含针对 Apple 平台上沙盒应用程序的重要信息,包括通过 Apple App Store 获取的所有应用程序。

另请参阅 《进程间通信》(Inter-ProcessCommunication)、QSharedMemory 以及QSemaphore 。

成员类型文档

enum QSystemSemaphore::AccessMode

该枚举由构造函数和setKey() 方法使用。其目的是为处理 Unix 系统中信号量在系统崩溃后仍存活的问题提供支持。在 Unix 系统中,当信号量在系统崩溃后仍存活时,当系统重新使用该信号量时,我们需要一种方法来强制将其资源计数重置。 在 Windows 系统中,由于信号量无法在崩溃后存活,此枚举无实际作用。

常量值描述
QSystemSemaphore::Open0如果信号量已存在,则其初始资源计数不会被重置。如果信号量尚不存在,则会创建该信号量并设置其初始资源计数。
QSystemSemaphore::Create1QSystemSemaphore 将接管该信号量,并将其资源计数设置为请求的值,无论该信号量是否因系统崩溃后幸存而已经存在。当为特定键构建第一个信号量时,且您知道如果该信号量已经存在,那只能是因为系统崩溃所致,应将此值传递给构造函数。 在 Windows 系统中,由于信号量无法在系统崩溃后存活,Create 和 Open 的行为相同。

enum QSystemSemaphore::SystemSemaphoreError

常数值描述
QSystemSemaphore::NoError0未发生错误。
QSystemSemaphore::PermissionDenied1操作失败,因为调用者没有所需的权限。
QSystemSemaphore::KeyError2操作失败,原因是密钥无效。
QSystemSemaphore::AlreadyExists3操作失败,因为已存在具有指定键的系统信号量。
QSystemSemaphore::NotFound4操作失败,因为找不到具有指定键的系统信号量。
QSystemSemaphore::OutOfResources5操作失败,因为可用内存不足以满足请求。
QSystemSemaphore::UnknownError6发生了其他情况,且情况不妙。

成员函数文档

QSystemSemaphore::QSystemSemaphore(const QNativeIpcKey &key, int initialValue = 0, QSystemSemaphore::AccessMode mode = Open)

请求为指定的key 分配一个系统信号量。参数initialValue 和mode 的使用遵循以下规则,这些规则因系统而异。

在 Unix 中,如果mode 为Open ,且系统中已存在一个由key 标识的信号量,则使用该信号量,且该信号量的资源计数不会被更改,即initialValue 将被忽略。 但如果系统中尚不存在标识为key 的信号量,则会为该键创建一个新的信号量,并将该信号量的资源计数设置为initialValue 。

在 Unix 中,如果mode 为Create ,且系统已存在由key 标识的信号量,则使用该信号量,并将其资源计数设置为initialValue 。如果系统尚未存在由key 标识的信号量,则会为该键创建一个新信号量,并将其资源计数设置为initialValue 。

在 Windows 系统中,mode 参数将被忽略,系统始终会尝试为指定的key 创建一个信号量。如果系统中尚不存在标识为key 的信号量,则会创建该信号量并将资源计数设置为initialValue 。但如果系统中已存在标识为key 的信号量,则会使用该信号量并忽略initialValue 。

mode 参数仅在Unix系统中使用,用于处理信号量在进程崩溃后仍存活的情况。 在这种情况下,下一个尝试分配具有相同key 的信号量的进程将获得该在进程崩溃后幸存的信号量;除非mode 被设置为Create ,否则资源计数不会重置为initialValue ,而是保留崩溃进程赋予的初始值。

另请参阅 acquire() 和key()。

QSystemSemaphore::QSystemSemaphore(const QString &key, int initialValue = 0, QSystemSemaphore::AccessMode mode = Open)

请求一个由旧版密钥key 标识的系统信号量。

[noexcept] QSystemSemaphore::~QSystemSemaphore()

析构函数会销毁QSystemSemaphore 对象,但除非该QSystemSemaphore 实例是该系统信号量下最后一个存在的实例,否则系统中的底层信号量不会被移除。

析构函数的两个重要副作用取决于系统。在 Windows 中,如果已为该信号量调用了acquire() 但未调用release(),则析构函数不会调用release(),且当进程正常退出时,该资源也不会被释放。 这将构成一个程序错误,可能导致另一个试图获取同一资源的进程陷入死锁。在 Unix 系统中,若在析构函数被调用之前未释放已获取的资源,则这些资源会在进程退出时自动释放。

bool QSystemSemaphore::acquire()

如果该信号量所保护的资源中有可用资源,则获取其中一个,并返回true 。如果该信号量所保护的所有资源均已被获取,则该调用将阻塞,直到另一个具有相同键的信号量的进程或线程释放其中一个资源为止。

如果返回 false,则表示发生了系统错误。调用error() 可获取QSystemSemaphore::SystemSemaphoreError 的值,该值指示发生了何种错误。

另请参阅 release()。

QSystemSemaphore::SystemSemaphoreError QSystemSemaphore::error() const

返回一个值,用于指示是否发生了错误;如果发生了错误,则返回具体是哪种错误。

另请参阅 errorString()。

QString QSystemSemaphore::errorString() const

返回上次发生的错误的文本描述。如果error()返回error value ,请调用此函数以获取描述该错误的文本字符串。

另请参阅 ` error()`。

QString QSystemSemaphore::key() const

返回分配给此系统信号量的旧式键。该键是其他进程访问该信号量时所使用的名称。

另请参阅 ` setKey()`。

QNativeIpcKey QSystemSemaphore::nativeIpcKey() const

返回分配给此系统信号量的键。该键是其他进程访问该信号量时所使用的名称。

您可以使用本机键访问非由 Qt 创建的系统信号量,或向非 Qt 应用程序授予访问权限。有关更多信息,请参阅“本机 IPC 键”。

另请参阅 ` setNativeKey()`。

bool QSystemSemaphore::release(int n = 1)

释放由该信号量保护的n 资源。除非发生系统错误,否则返回true 。

示例:创建一个拥有五个资源的系统信号量;获取所有资源,然后释放所有资源。

QSystemSemaphore sem(QSystemSemaphore::platformSafeKey("market"), 5, QSystemSemaphore::Create);
for (int i = 0; i < 5; ++i)  // acquire all 5 resources
    sem.acquire();
sem.release(5);              // release the 5 resources

该函数还可以“创建”资源。例如,紧接在上述语句序列之后,假设我们添加以下语句:

sem.release(10);          // "create" 10 new resources

现在,除了原有的五个资源外,还有十个新资源由该信号量保护。通常情况下,您不会使用此函数来创建更多资源。

另请参阅 acquire()。

void QSystemSemaphore::setKey(const QString &key, int initialValue = 0, QSystemSemaphore::AccessMode mode = Open)

该函数的工作原理与构造函数相同。它会重建此QSystemSemaphore 对象。如果新的key 与旧的键不同,则调用此函数的效果相当于先使用旧键调用信号量的析构函数,然后调用构造函数使用新的key 创建一个新的信号量。参数initialValue 和mode 的定义与构造函数中的定义相同。

另请参阅 QSystemSemaphore() 和key()。

void QSystemSemaphore::setNativeKey(const QNativeIpcKey &key, int initialValue = 0, QSystemSemaphore::AccessMode mode = Open)

该函数的工作原理与构造函数相同。它会重建此QSystemSemaphore 对象。如果新的key 与旧的密钥不同,调用此函数的效果相当于先使用旧密钥调用信号量的析构函数,然后调用构造函数使用新的key 创建一个新的信号量。参数initialValue 和mode 的定义与构造函数中的定义一致。

如果本机密钥是从另一个进程共享过来的,此函数会非常有用。有关更多信息,请参阅“本机 IPC 密钥”。

另请参阅 QSystemSemaphore() 和nativeIpcKey()。

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