C++消费者和生产者代码

单个生产者和单个消费者

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

using namespace std;

//任务队列
class BlockQueue {
public:
    BlockQueue(size_t _capacity) : capacity(_capacity) {};

    void push(const string& item) {
        unique_lock<mutex> lock(mtx);
        cond_product.wait(lock, [this]() {return queue.size() < capacity; });
        queue.push(item);
        cond_consumer.notify_one();
    }

    string take (){
        unique_lock<mutex> lock(mtx);
        cond_consumer.wait(lock, [this]() {return !queue.empty(); });
        string item = queue.front();
        queue.pop();
        cond_product.notify_one();
        return item;
    }
private:
    queue<string> queue;
    mutex mtx;
    condition_variable cond_product, cond_consumer;
    size_t capacity;
};

//生产者
void producer(BlockQueue& q) {
    for (int i = 0; i < 20; ++i) {
        string product = "Product" + to_string(i + 1);
        cout << "Producter producted: " << product << endl;
        q.push(product);
        this_thread::sleep_for(chrono::seconds(1));
    }
}


//消费者
void consumer(BlockQueue& q) {
    while (true) {
        string product = q.take();
        cout << "Consumer consumed: " << product << endl;
        this_thread::sleep_for(chrono::milliseconds(1500));
    }
}

//主程序
int main() {
    //最多20个任务
    BlockQueue q(20);

    thread producerThread(producer, ref(q));
    thread consumerThread(consumer, ref(q));
    producerThread.join();
    consumerThread.join();
    return 0;
}

单生产者和多消费者

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

using namespace std;

class BlockQueue {
public:
    BlockQueue(size_t _capacity) : capacity(_capacity) {}

    void push(const string& item) {
        unique_lock<mutex> lock(mtx);
        cond_product.wait(lock, [this]() { return queue.size() < capacity; });
        queue.push(item);
        cond_consumer.notify_one();
    }

    string take() {
        unique_lock<mutex> lock(mtx);
        cond_consumer.wait(lock, [this]() { return !queue.empty(); });
        string item = queue.front();
        queue.pop();
        cond_product.notify_one();
        return item;
    }

private:
    queue<string> queue;
    mutex mtx;
    condition_variable cond_product, cond_consumer;
    size_t capacity;
};

void producer(BlockQueue& q) {
    for (int i = 0; i < 20; ++i) {
        string product = "Product" + to_string(i + 1);
        cout << "Producer produced: " << product << endl;
        q.push(product);
        this_thread::sleep_for(chrono::seconds(1));
    }
}

void consumer(BlockQueue& q, int id) { // 增加消费者ID,用于区分不同消费者
    while (true) {
        string product = q.take();
        cout << "Consumer " << id << " consumed: " << product << endl;
        this_thread::sleep_for(chrono::milliseconds(1500)); // 模拟消费时间
    }
}

int main() {
    BlockQueue q(20);

    thread producerThread(producer, ref(q));

    // 创建多个消费者线程
    thread consumerThread1(consumer, ref(q), 1); // 消费者 1
    thread consumerThread2(consumer, ref(q), 2); // 消费者 2
    // 可以根据需要添加更多消费者
    // thread consumerThread3(consumer, ref(q), 3);

    producerThread.join();
    consumerThread1.join();
    consumerThread2.join();
    // consumerThread3.join(); // 如果添加了更多消费者线程,这里也需要 join

    return 0;
}
  1. 多个消费者线程:
    • 在 main() 函数中,增加了 consumerThread1 和 consumerThread2,分别传递了消费者的编号 1 和 2,用于区分不同的消费者。
    • 每个消费者线程独立运行,从 BlockQueue 中取出产品并进行消费。
  2. 区分消费者:
    • consumer 函数增加了一个 id 参数,用于打印时区分哪个消费者线程正在消费哪个产品。
  3. 扩展性:
    • 可以根据需要增加更多的消费者线程,只需在 main() 中创建更多的 thread consumerThreadX 并加入到程序中。

多生产者和单消费者

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

using namespace std;

class BlockQueue {
public:
    BlockQueue(size_t _capacity) : capacity(_capacity) {}

    void push(const string& item) {
        unique_lock<mutex> lock(mtx);
        cond_product.wait(lock, [this]() { return queue.size() < capacity; });
        queue.push(item);
        cond_consumer.notify_one();
    }

    string take() {
        unique_lock<mutex> lock(mtx);
        cond_consumer.wait(lock, [this]() { return !queue.empty(); });
        string item = queue.front();
        queue.pop();
        cond_product.notify_one();
        return item;
    }

private:
    queue<string> queue;
    mutex mtx;
    condition_variable cond_product, cond_consumer;
    size_t capacity;
};

void producer(BlockQueue& q, int id) { // 增加生产者ID,用于区分不同生产者
    for (int i = 0; i < 10; ++i) { // 每个生产者生产 10 个产品
        string product = "Product from Producer " + to_string(id) + ": " + to_string(i + 1);
        cout << "Producer " << id << " produced: " << product << endl;
        q.push(product);
        this_thread::sleep_for(chrono::milliseconds(500)); // 模拟生产时间
    }
}

void consumer(BlockQueue& q) {
    while (true) {
        string product = q.take();
        cout << "Consumer consumed: " << product << endl;
        this_thread::sleep_for(chrono::milliseconds(1500)); // 模拟消费时间
    }
}

int main() {
    BlockQueue q(20);

    // 创建多个生产者线程
    thread producerThread1(producer, ref(q), 1); // 生产者 1
    thread producerThread2(producer, ref(q), 2); // 生产者 2
    thread producerThread3(producer, ref(q), 3); // 生产者 3
    // 可以根据需要添加更多生产者

    // 创建一个消费者线程
    thread consumerThread(consumer, ref(q));

    producerThread1.join();
    producerThread2.join();
    producerThread3.join();
    consumerThread.join(); // 消费者线程在无限循环中,可以在需要时手动停止或退出

    return 0;
}

  1. 多个生产者线程:

    • 在 main() 函数中,创建了三个生产者线程 producerThread1、producerThread2、和 producerThread3,它们各自生产产品并将其放入队列中。
    • 每个生产者的输出带有其自身的 ID,用于区分不同的生产者。
  2. 单个消费者线程:

    • 只有一个消费者线程 consumerThread,它从 BlockQueue 中不断取出产品并消费。
  3. 线程同步:

    • 使用 std::mutex 和 std::condition_variable 保证生产者和消费者之间的同步,确保数据的安全访问。
  4. 循环与退出:

    • 消费者线程在无限循环中消费产品,实际应用中可以考虑添加退出条件或其他控制机制来停止消费者线程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值