Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- template<typename T, uint size = 1>
- struct Queue
- {
- bool push(const T& element)
- {
- uint oldWritePosition = writePosition.load(std::memory_order_relaxed);
- while (writePosition.compare_exchange_weak(oldWritePosition, getPositionAfter(oldWritePosition))) {
- if (getPositionAfter(oldWritePosition) == readPosition.load()) {
- //"pointing to the same area");
- return false;
- }
- ringBuffer[oldWritePosition] = element;
- return true;
- }
- return false;
- }
- bool pop(T& element)
- {
- uint oldWritePosition = writePosition.load(std::memory_order_relaxed);
- uint oldReadPosition = readPosition.load(std::memory_order_relaxed);
- while (readPosition.compare_exchange_strong(oldReadPosition, getPositionAfter(oldReadPosition))) {
- if (oldWritePosition == oldReadPosition) {
- //"pointing to the same area");
- return false;
- }
- element = ringBuffer[oldReadPosition];
- return true;
- } return false;
- }
- constexpr uint getPositionAfter(uint position) noexcept
- {
- return ++position == ringBufferSize ? 0 : position;
- }
- static constexpr uint ringBufferSize = size + 1;
- T ringBuffer[ringBufferSize];
- std::atomic<uint> writePosition = 0;
- std::atomic<uint> readPosition = 0;
- };
- int main()
- {
- std::vector<std::thread> producers, consumers;
- producers.resize(50);
- consumers.resize(50);
- Queue<int, 500> queue;
- std::mutex mutex;
- int k = 0;
- for (int i = 0; i < 50; ++i) {
- producers[i] = std::thread([&]() {
- queue.push(k);
- ++k;
- });
- }
- for (int i = 0; i < 50; ++i) {
- consumers[i] = std::thread([&]() {
- int j = 0;
- while (!queue.pop(j));
- std::lock_guard<std::mutex> guard(mutex);
- std::cout << j << std::endl;
- });
- }
- for (auto& producer : producers) {
- producer.join();
- }
- for (auto& consumer : consumers) {
- consumer.join();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement