消息队列介绍

C++中的消息队列是一种数据结构或容器,用于在多个线程之间进行异步通信和数据传输。它基于先进先出(FIFO)的原则,即最先发送的消息最先被接收和处理。

优点:

  • 异步通信:
    消息队列支持异步通信,发送者和接收者可以独立运行,不需要等待对方的响应;即发送者可以将消息放入队列后立即返回,而不需要等待接收者处理。这种异步通信能够提高系统的响应性能和并发性。
  • 解耦合:
    消息队列可以实现解耦合,即发送者和接收者之间的耦合度降低;发送者和接收者之间不需要直接通信,它们只需要通过消息队列关注消息的发送和接收,而不需要知道对方的具体实现细节。这样可以降低组件之间的耦合度,提高代码的可维护性和可扩展性。
  • 缓冲能力:
    消息队列可以作为缓冲区,在发送者发送消息过快或接收者处理消息较慢时,消息可以在队列中等待被处理,可以缓解压力,避免数据丢失。
  • 灵活性:
    消息队列可以支持多对多的通信模式,多个发送者可以同时发送消息给一个接收者,或者多个接收者可以同时接收来自一个发送者的消息。

缺点:

  • 时间开销:
    使用消息队列需要额外的时间开销,包括消息的发送、接收和处理。在高性能要求的场景中,这些额外的开销可能会对系统性能产生一定的影响。
  • 数据一致性:
    由于消息队列是异步通信的方式,发送者和接收者之间存在时间差,可能导致数据的一致性问题。在某些场景下,需要额外的机制来保证数据的一致性。
  • 可靠性:
    消息队列在发送消息后无法保证一定能被接收到,如果接收者不可用或者消息队列满了,消息可能会丢失。
  • 内存开销:
    消息队列需要占用一定的内存空间来存储消息,如果消息过多或过大,可能会导致内存消耗过大。

使用场景:

  • 多线程通信:
    在多线程应用中,消息队列可以作为线程之间进行通信和同步的机制,用于传递数据和控制信息。
  • 分布式系统:
    在分布式系统中,消息队列可以用于不同节点之间的通信和协调,实现异步处理和解耦合。
  • 异步任务处理:
    消息队列可以用于将任务提交到队列中,由后台的工作线程异步处理,提高系统的并发性和响应性。

线程安全示例

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

template <typename T>
class ThreadSafeQueue {
public:
    ThreadSafeQueue(int maxQueueSize = -1) : maxQueueSize_(maxQueueSize) {}
    bool Push(const T& value, int timeoutMs = -1) {
        std::unique_lock<std::mutex> lock(mutex_);
        if (timeoutMs < 0) {	// 不设置超时
            condition_.wait(lock, [this]() { return maxQueueSize_ < 0 || queue_.size() < maxQueueSize_; });
        } else {	// 设置超时
            if (!condition_.wait_for(lock, std::chrono::milliseconds(timeoutMs), [this]() { return maxQueueSize_ < 0 || queue_.size() < maxQueueSize_; })) {
                return false; // 超时返回false
            }
        }
        queue_.push(value);
        condition_.notify_one();
        return true;
    }
    bool Pop(T& value, int timeoutMs = -1) {
        std::unique_lock<std::mutex> lock(mutex_);
        if (timeoutMs < 0) {	// 不设置超时
            condition_.wait(lock, [this]() { return !queue_.empty(); });
        } else {	// 设置超时
            if (!condition_.wait_for(lock, std::chrono::milliseconds(timeoutMs), [this]() { return !queue_.empty(); })) {
                return false; // 超时返回false
            }
        }
        value = queue_.front();
        queue_.pop();
        return true;
    }
private:
    std::queue<T> queue_; // 内部使用的队列
    std::mutex mutex_; // 互斥锁,保护队列访问
    std::condition_variable condition_; // 条件变量,用于线程等待和唤醒
    int maxQueueSize_; // 队列最大长度,-1表示不限制长度
};
int main() {
    ThreadSafeQueue<int> messageQueue(5);
    std::thread producer([&messageQueue]() {
        for (int i = 1; i <= 10; ++i) {
            if (messageQueue.Push(i, 1000)) {	std::cout << "Produced: " << i << std::endl;	}
            else {	std::cout << "Timeout: " << i << std::endl;	}
            std::this_thread::sleep_for(std::chrono::milliseconds(500));
        }
    });
    std::thread consumer([&messageQueue]() {
        for (int i = 1; i <= 10; ++i) {
            int value;
            if (messageQueue.Pop(value, 1000)) {	std::cout << "Consumed: " << value << std::endl;	}
            else {	std::cout << "Timeout" << std::endl;	}
        }
    });
    producer.join();
    consumer.join();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值