c++ Channel 的实现

#include <iostream>
#include <queue>
#include <condition_variable>
#include <thread>
#include <cassert>
#include <memory>

using namespace std;

class Cv_Guard {
private:
    condition_variable &con;
public:
    explicit Cv_Guard(condition_variable &con) : con(con) {}

    ~Cv_Guard() {
        con.notify_one();
    }
};


template<typename T>
class Channel {
private:
    static constexpr int CHANNEL_SIZE_DEFAULT = 1;
    static constexpr int MICRO_SLEEP_TIME = 1;

    mutex m;
    condition_variable q_not_empty;
    queue<unique_ptr<T>> q;
    const int capacity;
    atomic_flag done;

    [[nodiscard]] int size() const {
        return q.size();
    }

public:
    [[nodiscard]] bool isDone() const {
        return done.test();
    }

    void close() {
        done.test_and_set();
    }

    explicit Channel(const int capacity = CHANNEL_SIZE_DEFAULT) : capacity(capacity) {
        assert(capacity > 0);
    }

    friend Channel &operator<<(Channel &ch, unique_ptr<T> data) {
        unique_lock<mutex> lock(ch.m);
        Cv_Guard cvg(ch.q_not_empty);
        while (!ch.isDone() && ch.size() >= ch.capacity) {
            lock.unlock();
            this_thread::sleep_for(chrono::microseconds(MICRO_SLEEP_TIME));
            lock.lock();
        }
        if (ch.isDone()) {
            return ch;
        }
        ch.q.push(move(data));
        return ch;
    }

    friend Channel &operator>>(Channel &ch, unique_ptr<T> &data) {
        unique_lock<mutex> lock(ch.m);
        ch.q_not_empty.wait(lock, [&ch] {
            return !(ch.q.empty() && !ch.isDone());
        });
        if (ch.isDone()) {
            return ch;
        }
        data = std::move(ch.q.front());
        ch.q.pop();
        return ch;
    }
};


void consumer(Channel<int>& chx) {
    unique_ptr<int> data;
    while (!chx.isDone()) {
        chx >> data;
        cout << *data << endl;
    }
}

void producer(Channel<int>& chx) {
    int i = 0;
    while (!chx.isDone()) {
        chx << make_unique<int>(i++);
    }
}

int main() {
    Channel<int> chx(100);
    thread consu(consumer, ref(chx));
    thread pro(producer, ref(chx));
    this_thread::sleep_for(chrono::seconds(1));
    chx.close();
    pro.join();
    consu.join();
}

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CSMA/CA协议是一种用于无线网络中的MAC协议,主要用于解决无线介质带来的冲突问题。下面是一个简单的C++实现。 首先,我们需要定义一个结构体来表示每个节点: ```c++ struct Node { int id; // 节点ID bool busy = false; // 是否繁忙 bool sent = false; // 是否发送了数据包 bool channel_busy = false; // 信道是否繁忙 int backoff = 0; // 后退指数 int cw = 4; // 竞争窗口大小 int cw_max = 1024; // 最大竞争窗口大小 int timeout = 16; // 超时时间 int rts_timeout = 4; // RTS超时时间 int cts_timeout = 4; // CTS超时时间 }; ``` 然后我们需要定义一些常量来表示一些参数: ```c++ const int NODE_NUM = 5; // 节点数量 const int SEND_NUM = 3; // 发送数据包数量 const int RTS_NUM = 2; // 发送RTS包数量 const int CTS_NUM = 2; // 发送CTS包数量 const int MAX_ROUND = 10; // 最大轮数 const int PACKET_SIZE = 1000; // 数据包大小 ``` 接下来我们实现一些辅助函数: ```c++ int rand_between(int a, int b) { // 随机生成a到b之间的整数 return rand() % (b - a + 1) + a; } void backoff(Node& node) { // 后退指数减一,如果为0则重传 if (node.backoff == 0) { node.cw = min(node.cw * 2, node.cw_max); node.sent = false; } else { node.backoff--; } } int channel_busy_count(vector<Node>& nodes) { // 统计信道繁忙的节点数量 int count = 0; for (auto& node : nodes) { if (node.channel_busy) { count++; } } return count; } void send_rts(Node& node, vector<Node>& nodes) { // 发送RTS包 node.busy = true; node.sent = true; node.channel_busy = true; node.backoff = rand_between(0, node.cw - 1); for (auto& n : nodes) { if (n.id != node.id) { n.channel_busy = true; } } } void send_cts(Node& node, vector<Node>& nodes) { // 发送CTS包 node.busy = true; node.sent = true; node.channel_busy = true; node.backoff = rand_between(0, node.cw - 1); for (auto& n : nodes) { if (n.id != node.id) { n.channel_busy = true; } } } void send_packet(Node& node, vector<Node>& nodes) { // 发送数据包 node.busy = true; node.sent = true; node.channel_busy = true; node.backoff = rand_between(0, node.cw - 1); for (auto& n : nodes) { if (n.id != node.id) { n.channel_busy = true; } } } void handle_packet(Node& node, vector<Node>& nodes) { // 处理数据包 node.busy = false; node.channel_busy = false; node.backoff = 0; node.cw = 4; node.sent = false; } ``` 最后我们实现主函数: ```c++ int main() { srand(time(0)); // 初始化随机种子 vector<Node> nodes(NODE_NUM); // 创建节点 int round = 1; while (round <= MAX_ROUND) { // 最多进行MAX_ROUND轮 cout << "Round " << round << endl; for (auto& node : nodes) { // 每个节点处理一次 if (node.busy) { // 如果节点繁忙,则后退指数减一 backoff(node); } else if (!node.sent) { // 如果节点没有发送过数据包 if (channel_busy_count(nodes) == 0) { // 如果信道空闲 if (rand() % 2 == 0) { // 有50%的概率发送数据包 send_packet(node, nodes); cout << "Node " << node.id << " sends a packet." << endl; } else { // 有50%的概率发送RTS包 send_rts(node, nodes); cout << "Node " << node.id << " sends an RTS packet." << endl; } } else { // 如果信道繁忙,则后退指数减一 backoff(node); } } else if (node.sent) { // 如果节点发送过数据包 if (node.timeout == 0) { // 如果超时,则后退指数减一 backoff(node); cout << "Node " << node.id << " times out." << endl; } else { node.timeout--; } } } for (auto& node : nodes) { // 处理RTS包和CTS包 if (node.sent && node.timeout == 0) { // 如果RTS或CTS超时 if (node.rts_timeout > 0) { // 如果是RTS超时,则重新发送RTS包 node.rts_timeout--; send_rts(node, nodes); cout << "Node " << node.id << " re-sends an RTS packet." << endl; } else if (node.cts_timeout > 0) { // 如果是CTS超时,则重新发送CTS包 node.cts_timeout--; send_cts(node, nodes); cout << "Node " << node.id << " re-sends a CTS packet." << endl; } else { // 如果RTS和CTS都超时,则后退指数减一 backoff(node); cout << "Node " << node.id << " times out." << endl; } } if (node.busy && node.sent && node.cts_timeout == 0) { // 如果CTS超时 backoff(node); cout << "Node " << node.id << " times out." << endl; } } for (auto& node : nodes) { // 处理收到的数据包 if (node.channel_busy) { // 如果信道繁忙 if (node.sent && node.rts_timeout > 0 && node.cts_timeout > 0) { // 如果节点发送过RTS包和CTS包 cout << "Node " << node.id << " receives a packet." << endl; handle_packet(node, nodes); } else { // 如果节点没有发送过RTS包和CTS包,则忽略数据包 cout << "Node " << node.id << " ignores a packet." << endl; } } } round++; } return 0; } ``` 这样我们就实现了一个简单的CSMA/CA协议的C++程序。注意这只是一个简单的实现,实际中可能需要根据具体情况进行一些修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值