QSystemSemaphore::acquire() 中止

QSystemSemaphore::acquire() abort

我使用 QSharedMemory 和 QSystemSemaphore 来组织多个进程之间的事件交换。 QSharedMemory 存储接收者的数量和事件数据。接收者正在 QSystemSemaphore::acquire() 中等待。发件人通过 QSystemSemaphore::release([收件人数量])通知他们。

除了在共享内存中引入标志 "real"/"fake" 并随后在终止进程中生成 "fake" 事件之外,是否有任何方式可以优雅地终止接收进程?

QThread::terminate() 适用于所有平台,无论线程此时正在做什么。当然,当您终止应用程序中的 any 线程时,您唯一可以安全做的另一件事就是调用 abort:此时进程通常处于中断状态. 不要 在调用 QThread::terminate 后做除 abort() 以外的任何事情。既然如此具有破坏性,你不妨放弃调用 terminate 并直接中止。

您的问题措辞好像您计划在致电 terminate 后继续申请。你不能!

唉,如果你只想让一个线程退出,信号量是一个同步原语,你可以通过设置一个标志并释放信号量来轻松地做到这一点。下面是一个有点做作的例子,因为你通常不会那样使用线程池:它只是为了让代码更短。

// https://github.com/KubaO/Whosebugn/tree/master/questions/semaphore-quit-40488523
#include <QtCore>

class Worker : public QRunnable {
    static const QString m_key;
    static QAtomicInteger<bool> m_abort;
    void run() override {
        QSystemSemaphore sem{m_key};
        qDebug() << "working";
        while (true) {
            sem.acquire();
            if (m_abort.load()) {
                sem.release();
                qDebug() << "aborting";
                return;
            }
            sem.release();
        }
    }
public:
    static void acquire(int n = 1) {
        QSystemSemaphore sem{m_key};
        while (n--)
            sem.acquire();
    }
    static void release(int n = 1) {
        QSystemSemaphore{m_key}.release(n);
    }
    static void quit(int n) {
        m_abort.store(true);
        release(n);
    }
};
const QString Worker::m_key = QStringLiteral("semaphore-quit-40488523");
QAtomicInteger<bool> Worker::m_abort = false;

int main()
{
    QThreadPool pool;
    QVarLengthArray<Worker, 20> workers{20};
    for (auto & worker : workers) {
        worker.setAutoDelete(false);
        pool.start(&worker);
    }
    Worker::release(workers.size()); // get some workers churning
    QThread::sleep(5);
    Worker::acquire(workers.size()); // pause all the workers
    Worker::quit(workers.size());
    // The thread pool destructor will wait for all workers to quit.
}