ZBLOG

c/c++ 实现有锁队列与无锁队列的性能对比 并编译测试

以下是一个简单的有锁队列(Lock-based Queue)和无锁队列(Lock-free Queue)的性能对比示例代码:

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

// 有锁队列
class LockBasedQueue {
public:
    void enqueue(int item) {
        std::lock_guard<std::mutex> lock(mutex_);
        queue_.push(item);
    }

    int dequeue() {
        std::lock_guard<std::mutex> lock(mutex_);
        if (!queue_.empty()) {
            int item = queue_.front();
            queue_.pop();
            return item;
        }
        return -1; // 队列为空时返回-1表示出错
    }

private:
    std::queue<int> queue_;
    std::mutex mutex_;
};

// 无锁队列
class LockFreeQueue {
public:
    void enqueue(int item) {
        Node* new_node = new Node(item);
        Node* prev_tail = tail_.exchange(new_node, std::memory_order_acq_rel);
        prev_tail->next.store(new_node, std::memory_order_release);
    }

    int dequeue() {
        Node* head = head_.load(std::memory_order_acquire);
        Node* next_head = head->next.load(std::memory_order_acquire);

        if (head != tail_) {
            int item = next_head->data;
            head_.store(next_head, std::memory_order_release);
            delete head;
            return item;
        }
        
        return -1; // 队列为空时返回-1表示出错
    }

private:
    struct Node {
        int data;
        std::atomic<Node*> next;

        Node(int val): data(val), next(nullptr) {}
    };

    alignas(64) std::atomic<Node*> head_;
    alignas(64) std::atomic<Node*> tail_;
};

// 测试函数
void testQueue(int num_threads, int num_ops, bool use_lock_based_queue) {
    std::cout << (use_lock_based_queue ? "Lock-based Queue" : "Lock-free Queue") << std::endl;

    std::queue<int> expected_result;
    LockBasedQueue lock_based_queue;
    LockFreeQueue lock_free_queue;

    auto enqueue_func = [&](int id) {
        for (int i = 0; i < num_ops; ++i) {
            if (use_lock_based_queue)
                lock_based_queue.enqueue(id * num_ops + i);
            else
                lock_free_queue.enqueue(id * num_ops + i);
        }
    };

    auto dequeue_func = [&]() {
        for (int i = 0; i < num_threads * num_ops; ++i) {
            int item;
            if (use_lock_based_queue)
                item = lock_based_queue.dequeue();
            else
                item = lock_free_queue.dequeue();

            if (item != -1)
                expected_result.push(item);
        }
    };

    // 启动线程进行操作
    std::vector<std::thread> threads(num_threads);
    
    for (int i = 0; i < num_threads; ++i)
        threads[i] = std::thread(enqueue_func, i);

    for (auto& thread : threads)
        thread.join();

    threads.clear();

    for (int i = 0; i < num_threads; ++i)
        threads.emplace_back(dequeue_func);

    for (auto& thread : threads)
        thread.join();

    // 检查结果是否一致
    bool is_correct = true;
    
    while (!expected_result.empty()) {
        int expected = expected_result.front();
        expected_result.pop();

        if (expected != -1) {
            int actual = use_lock_based_queue ? lock_based_queue.dequeue() : lock_free_queue.dequeue();
            
            if (actual != expected) {
                std::cout << "Mismatch: Expected " << expected << ", Actual " << actual << std::endl;
                is_correct = false;
                break;
            }
        }
    }

    if (is_correct)
        std::cout << "Results are correct." << std::endl;

    std::cout << std::endl;
}

int main() {
    const int num_threads = 4;
    const int num_ops_per_thread = 100000;

    testQueue(num_threads, num_ops_per_thread, true);   // 测试有锁队列
    testQueue(num_threads, num_ops_per_thread, false);  // 测试无锁队列

    return 0;
}

上述代码中,我们实现了一个基于互斥锁的有锁队列(LockBasedQueue)和一个无锁队列(LockFreeQueue)。在测试函数中,我们创建了多个线程来同时对队列进行入队和出队操作,并检查最终结果是否正确。

你可以将以上代码保存到一个.cpp文件中,并使用C++编译器进行编译和运行。例如,使用g++编译器:

g++ -std=c++11 -o queue_performance_test queue_performance_test.cpp -lpthread
./queue_performance_test

请注意,在不同的硬件平台上,性能对比结果可能会有所不同。为了准确评估两种队列的性能,请根据自己的需求和硬件环境进行测试。


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

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?