首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >生产者-消费者在C++ -跟进

生产者-消费者在C++ -跟进
EN

Code Review用户
提问于 2015-09-21 13:12:40
回答 1查看 1.1K关注 0票数 2

要从我上一个问题的答案所提供的更改中展开:

代码语言:javascript
复制
#include <condition_variable>
#include <iostream>
#include <random>
#include <mutex>
#include <thread>
#include <vector>

// global variables
std::condition_variable cv;
std::mutex mtx;
std::vector<char> data;

int count = 0, buff_size = 0;

char random_char() {
    thread_local std::random_device seed;
    thread_local std::mt19937 generator(seed());
    thread_local std::uniform_int_distribution<int> dist('A', 'Z');

    return static_cast<char>(dist(generator));
}

/* Consumer

Prints out the contents of the shared buffer.

*/
void consume() {
    std::unique_lock<std::mutex> lck(mtx);

    while (count == 0) {
        cv.wait(lck);
    }

    for (const auto& it : data) {
        std::cout << it << std::endl;
    }

    count--;
}

/* Producer

Randomly generates capital letters in the range of A to Z,
prints out those letters in lowercase, and then
inserts them into the shared buffer.

*/
void produce() {
    std::unique_lock<std::mutex> lck(mtx);

    char c = random_char();
    std::cout << " " << static_cast<char>(tolower(c)) << std::endl;
    data.push_back(c);

    count++;
    cv.notify_one();
}

int main() {
    std::cout << "The Producer-Consumer Problem (in C++11!)" << std::endl << "Enter the buffer size: ";
    std::cin >> buff_size;

    // keep the buffer in-range of the alphabet
    if (buff_size < 0) {
        buff_size = 0;
    }
    else if (buff_size > 26) {
        buff_size = 26;
    }

    std::thread production[26], processed[26];

    // initialize the arrays
    for (int order = 0; order < buff_size; order++) {
        production[order] = std::thread(produce);
        processed[order] = std::thread(consume);
    }

    // join the threads to the main threads
    for (int order = 0; order < buff_size; order++) {
        processed[order].join();
        production[order].join();
    }

    std::cout << "Succeeded with a shared buffer of " << data.size() << " letters!";
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2015-09-21 14:35:54

在最好的情况下,全局变量是有问题的,但在本例中,尤其是将buff_size作为全局变量。buff_size只在main()中使用,因此应该是一个局部变量。

您还可以利用以下事实:std::condition_variable::wait()还有另一个重载,需要一个谓词来替换:

代码语言:javascript
复制
while (count == 0) {
    cv.wait(lck);
}

通过以下方式:

代码语言:javascript
复制
cv.wait(lck, []{ return count > 0; });

不过,你真的想让每个消费者每次都打印出每封信吗?如果buff_size是10,你最终会记录55个字母。那是故意的吗?如果不是,您可以完全放弃count,将data切换为std::queue,并让您的消费者:

代码语言:javascript
复制
std::unique_lock<std::mutex> lck(mtx);
cv.wait(lck, []{return !data.empty(); });
std::cout << data.front() << std::endl;
data.pop();

在制片人方面,你是指notify_one()而不是notify_all()吗?让所有的消费者为锁而战!

最后,这一点:

代码语言:javascript
复制
if (buff_size < 0) {
    buff_size = 0;
}
else if (buff_size > 26) {
    buff_size = 26;
}

是个夹子。也许值得写这样的东西:

代码语言:javascript
复制
template <typename T>
T clamp(T const& val, T const& lo, T const& hi)
{
    return std::min(std::max(val, lo), hi);
}

buff_size = clamp(buff_size, 0, 26);
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/105253

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档