消息队列

  • 1. 概述
  • 2. 案例分析
  • 案例构建
  • 实现代码
  • 具体分析
  • 运行结果


1. 概述

  消息队列(Message Queue)是一种用于在分布式系统中进行异步通信的通信模型。它允许应用程序通过发送和接收消息来实现解耦异步通信,从而实现系统间的解耦高可伸缩性。
  消息队列通常由两个主要组件组成:生产者(Producer)和消费者(Consumer)。生产者负责将消息发送到消息队列,而消费者则负责从消息队列中接收并处理消息。消息队列会保存消息,直到消费者准备好处理它们。
  消息队列还可以具有一些其他的特性,例如持久化消息确认机制消息优先级消息过期等。它们可以用于解决一些常见的分布式系统通信问题,如解耦不同服务之间的依赖关系、处理高峰时期的流量、处理异步任务等。
  消息队列在许多应用场景中得到广泛应用,例如大规模分布式系统、微服务架构、事件驱动架构、日志处理、任务队列、消息推送、实时数据处理等。一些常见的消息队列系统包括 RabbitMQ、Apache Kafka、ActiveMQ、Redis、ZeroMQ 等。

2. 案例分析

  话不多说,直接上代码。这里我们使用C++来实现一个简单的消息队列。

案例构建

  为实现一个简单的生产者-消费者模型的实现,使用了C++11标准库中的互斥锁(std::mutex)条件变量(std::condition_variable)队列(std::queue)来实现线程间的同步和通信。

实现代码

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

std::queue<int> q; // 消息队列
std::mutex mtx; // 互斥锁,用于保护消息队列
std::condition_variable cv; // 条件变量,用于线程间的条件通知

// 生产者线程函数
void producer() {
    for (int i = 0; i < 10; ++i) {
        std::unique_lock<std::mutex> lock(mtx);
        q.push(i); // 生产消息
        std::cout << "Producer: produced " << i << std::endl;
        lock.unlock();
        cv.notify_one(); // 通知消费者线程
        std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 模拟生产间隔
    }
}

// 消费者线程函数
void consumer() {
    while (true) {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [] { return !q.empty(); }); // 等待消息队列非空
        int msg = q.front(); // 消费消息
        q.pop();
        lock.unlock();
        std::cout << "Consumer: consumed " << msg << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 模拟消费耗时
    }
}

int main() {
    std::thread producerThread(producer); // 创建生产者线程
    std::thread consumerThread(consumer); // 创建消费者线程

    producerThread.join(); // 等待生产者线程结束
    consumerThread.join(); // 等待消费者线程结束

    return 0;
}

具体分析

  1. std::queue<int> q;:定义了一个整数类型的队列q,作为消息队列,用于存放生产者生产的消息。
  2. std::mutex mtx;:定义了一个互斥锁mtx,用于保护对消息队列的并发访问。生产者和消费者线程都会在访问消息队列时通过该互斥锁进行加锁和解锁,以确保对消息队列的访问是线程安全的。
  3. std::condition_variable cv;:定义了一个条件变量cv,用于线程间的条件通知。消费者线程会在条件变量上等待,直到有消息可以消费时,通过条件变量被唤醒。
  4. void producer():生产者线程函数,负责往消息队列中生产消息。每生产一条消息,就会通过互斥锁保护的临界区域将消息放入队列,然后通过条件变量cv.notify_one()通知消费者线程有消息可消费。
  5. void consumer():消费者线程函数,负责从消息队列中消费消息。消费者线程通过条件变量cv.wait()在条件变量上等待,直到有消息可以消费时被唤醒。然后通过互斥锁保护的临界区域从队列中取出消息,并进行处理。
  6. int main():主函数,创建了一个生产者线程和一个消费者线程,并通过std::thread类的join()函数等待线程结束,确保生产者和消费者线程都执行完毕。

  这段代码实现了一个简单的生产者-消费者模型,通过互斥锁和条件变量实现了线程间的同步和通信,确保生产者生产的消息能够被消费者消费,并且在队列为空时,消费者线程会等待,避免了忙等待的情况。需要注意的是,这只是一个简单的示例代码,实际生产环境中可能需要考虑更多的细节,例如错误处理线程安全性性能等。

运行结果

如何用消息队列做补偿机制 消息队列queue_linux