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

C++中的生产者-消费者
EN

Code Review用户
提问于 2015-09-18 03:57:49
回答 1查看 6K关注 0票数 6

这是我第一次尝试生产者-消费者问题(以及一般的线程操作),所以任何关于禁忌和修复的反馈都是非常感谢的!

代码语言:javascript
复制
#include <condition_variable>
std::condition_variable cv;

#include <iostream>
#include <random>

#include <mutex>
std::mutex mtx;

#include <thread>

// standard in all of my programs
void panic(const std::string &msg) {
    throw std::runtime_error("Error: " + msg + "\n");
}

int count = 0, buff_size = 0;
char* buff;

int random_int(int lower_bound) {
    std::random_device seed;
    std::mt19937 generator(seed());
    std::uniform_int_distribution<int> dist(lower_bound, std::nextafter(26, DBL_MAX));

    return dist(generator);
}

char random_char(int lower_bound) {
    return 'A' + (random_int(lower_bound) % 26);
}

/* Consumer

Reads characters from the buffer and prints them.

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

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

    /*
    job + 1 = Running
    job = Ready
    */
    for (int i = 0; i < buff_size; i++) {
        std::cout << buff[i] << std::endl;
    }

    count--;
}

/* Producer

Randomly generates letters at (pos > buff_size & pos <= 26),
inserts them at the next available position in the buffer,
and then prints out the lowercase form of the inputted letter.

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

    for (int i = 0; i < buff_size; i++) {
        buff[i] = random_char(buff_size);
        std::cout << static_cast<char>(tolower(buff[i])) << std::endl;
    }

    count++;
    cv.notify_one();
}

int main() {
    int buf_size = 0;

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

    if (buf_size > 0 && buf_size <= 26) {
        // set the buffer size
        buff_size = buf_size;
        buff = new char[buff_size];
    }
    else {
        // rage quit
        panic("The range must be > 0 and <= 26.");
    }

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

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

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

回答 1

Code Review用户

发布于 2015-09-19 21:18:03

我从@Mat的答案中修改的代码:

代码语言: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!";
}
票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

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

复制
相关文章

相似问题

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