ZBLOG

std::atomic m_lock;//队列正在析构

在 C++ 中,std::atomic<bool> 是一个用于实现原子操作的布尔类型,它保证了对该变量的读写操作是线程安全的。在您提到的上下文中,“队列正在析构”的意思可能是指一个多线程环境中的队列类,在其析构期间需要确保不会有其他线程访问该队列。

下面是如何使用 std::atomic<bool> 来标识队列是否正在被析构的一种示例实现:

示例代码

#include <iostream>
#include <thread>
#include <queue>
#include <atomic>
#include <chrono>

class ThreadSafeQueue {
public:
    ThreadSafeQueue() : m_lock(false) {}
    
    void enqueue(int value) {
        std::unique_lock<std::mutex> lock(m_mutex);
        // 只有在队列没有被析构时才能入队
        if (!m_lock.load()) {
            m_queue.push(value);
            std::cout << "Enqueued: " << value << "\n";
        } else {
            std::cerr << "Cannot enqueue, queue is being destructed.\n";
        }
    }

    bool dequeue(int& result) {
        std::unique_lock<std::mutex> lock(m_mutex);
        if (!m_queue.empty() && !m_lock.load()) {
            result = m_queue.front();
            m_queue.pop();
            return true;
        }
        return false;
    }

    ~ThreadSafeQueue() {
        // 标记为正在析构
        m_lock.store(true);
        
        // 等待所有入队和出队操作完成(这里简单地休眠一下以演示)
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        
        while (!m_queue.empty()) { 
            int value;
            dequeue(value); // 清空剩余元素
            std::cout << "Dequeued during destruction: " << value << "\n";
        }
        
        std::cout << "Queue destructed.\n";
    }

private:
    std::queue<int> m_queue;
    mutable std::mutex m_mutex; // 互斥锁,用于保护访问共享资源
    std::atomic<bool> m_lock;   // 用于标记是否正在析构
};

void producer(ThreadSafeQueue& q) {
    for (int i = 0; i < 5; ++i) {
        q.enqueue(i);
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
    }
}

void consumer(ThreadSafeQueue& q) {
    int value;
    for (int i = 0; i < 5; ++i) {
       if (q.dequeue(value)) {
           std::cout << "Consumer got: " << value << "\n";
       } else {
           std::cerr << "Consumer couldn't dequeue.\n";
       }
       std::this_thread::sleep_for(std::chrono::milliseconds(60));
   }
}

int main() {
    ThreadSafeQueue queue;

    std::thread t1(producer, std::ref(queue));
    std::thread t2(consumer, std::ref(queue));

    t1.join();
    
	// 确保生产者先结束,再让消费者结束。
	std :: this_thread :: sleep_for(std :: chrono :: milliseconds (500));

	queue.~ThreadSafeQueue(); 

	t2.join();

	return 0;
}

说明

  1. stdatomic:使用 stdatomic 可以确保对 m_lock 的读取和写入是原子的,避免了数据竞争的问题。

  2. 入队和出队方法:在 enqueue()dequeue() 方法中,我们首先检查 m_lock 是否为 false,以确保在队列未被销毁时才允许进行这些操作。

  3. 析构函数:在析构函数中,我们将 m_lock 设置为 true,表明当前对象正处于析构过程中。此后我们可以清空任何残留的数据,而不会影响到新的入队或出队操作。

  4. 多线程场景:为了演示这段代码,我们创建了一个生产者和消费者线程。这些线程会并发地对我们的线程安全队列进行操作。

这种设计模式确保了即使在多线程环境中,也能够正确地管理对资源的访问,并避免因同时访问而导致的不确定性行为。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=22664

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?