QSemaphore是否足以制作QQueue的线程安全模拟
Is QSemaphore enough to make a thread safe analogue of QQueue?
我试图对QQueue进行基本的线程安全模拟。这个想法是一个线程将数据放入队列,另一个线程处理它。我已经找到了一个非常基本的解决方案。
#include <QThread>
#include <QQueue>
#include <QSemaphore>
class AsyncQueue
{
public:
void enqueue(const int x);
int dequeue();
private:
QQueue<int> queue;
QSemaphore semaphore;
};
int AsyncQueue::dequeue()
{
semaphore.acquire();
return queue.dequeue();
}
void AsyncQueue::enqueue(const int x)
{
queue.enqueue(x);
semaphore.release();
return;
}
我是多线程的新手。它通过了一些最简单的测试,但我想知道这是否足够?或者队列是否需要AtomicPointer,以防线程在处理队列的最后一个项目时尝试将新项目排入队列?
事实并非如此,因为没有关键部分保护enqueue()
对队列的写访问,因此有机会对队列进行并发读/写访问。它总是可以执行,因为QSemaphore::release()
永远不会阻塞。因此,dequeue()
和enqueue(int)
有很多机会同时执行,造成严重破坏。
您现在拥有的信号量完成了向队列的使用者端发送队列中存在的值的数量的信号的角色。您将需要第二个QSemaphore
来实现对底层QQueue
的独占访问,如下所示(经过非常肤浅的测试(:
#include <QThread>
#include <QQueue>
#include <QSemaphore>
class AsyncQueue
{
public:
void enqueue(const int x);
int dequeue();
private:
QQueue<int> queue;
QSemaphore itemsInQueue;
QSemaphore exclusiveAccess{1};
};
int AsyncQueue::dequeue()
{
itemsInQueue.acquire();
exclusiveAccess.acquire();
int result{queue.dequeue()};
exclusiveAccess.release();
return result;
}
void AsyncQueue::enqueue(const int x)
{
exclusiveAccess.acquire();
queue.enqueue(x);
exclusiveAccess.release();
itemsInQueue.release();
}
如果您可以使用现代编译器,我更喜欢使用STL对应程序来实现这一点。std::thread
、std::mutex
、std::lock_guard
和std::condition_variable
在这种情况下值得研究。
我认为您可以按照下面的说明进行尝试。
基本上文件上写着:
QSharedPointer和QWeakPointer是线程安全的,并且以原子方式操作指针值。不同的线程也可以访问同时指向同一对象的QSharedPointer或QWeakPointer时间而不需要锁定机制。
因此您不需要锁定机制。。。。。
如何:
using sInt = QSharedPointer<int>;
QQueue<sInt> qInt; //Your queue of shared pointer objects.
qInt.enqueue(QSharedPointer<int>::create(5));
qInt.enqueue(QSharedPointer<int>::create(6));
qInt.enqueue(QSharedPointer<int>::create(7));
qInt.enqueue(QSharedPointer<int>::create(8));
//To retrieve the value use either data() or get() as shown below.
sInt value = qInt.dequeue();
int *val = value.data();
相关文章:
- 如何将元素添加到数组的线程安全函数?
- C++中的线程安全删除
- 在std::thread中,joinable()然后join()线程安全吗
- 在c++队列中使用pop和visit实现线程安全
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 全局变量 多读取器 一个写入器多线程安全?
- 共享队列的线程安全
- boost::文件系统::recursive_directory_iterator多线程安全
- 以线程安全的方式转换 C/C++ 中时区名称字符串的时区偏移量
- 线程安全运算符<<
- 如何使缓存线程安全
- C++线程安全:如果只有一个线程可以写入非原子变量,但多个线程从中读取. 会遇到问题吗?
- 提升精神 V2 Qi 语法线程安全吗?
- asio 链对象线程安全吗?
- 线程安全队列 c++
- 提供对不同类型的数据(建议、代码审查)的线程安全访问的类
- 如何以线程安全的方式更改目录?
- 线程安全的引用计数队列C++
- 析构函数和线程安全
- 适用于大型数组的无复制线程安全环形缓冲区