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.
}
我使用 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.
}