Я начал изучать манипуляции с потоками и начал с простой программы, предназначенной для генерации случайных заглавных букв. Буквы произвольно генерируются и добавляются в массив символов через производителя, а любые добавленные выводятся как строчные. Потребитель просто выводит обычную заглавную букву из массива char. До сих пор у меня было следующее:Продюсер-потребитель в C++ 11
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <random>
std::mutex mtx;
std::condition_variable cv;
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 << 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
exit(1);
}
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();
}
// free the allocated memory
delete[] buff;
}
Мой выход, однако, представляет собой смесь заглавных букв и случайных чисел. Что не так? Это мой первый эксперимент, так что будьте осторожны. :)
Вы отметили C++ 11 в этом сообщении, и я также вижу в вашем коде 'buff = new char [buff_size]'. Я бы рекомендовал использовать 'std :: vector' вместо массива или, по крайней мере, с помощью интеллектуального указателя типа' std :: unique_ptr' или 'std :: shared_ptr' для управления динамически распределенными вещами - они помогут вам не забудьте удалить их. – Steve
'std :: tolower' возвращает' int'. – zch
@Steve Спасибо за рекомендацию! Я собирался использовать такую структуру данных, как это, но поскольку это моя первая попытка, я просто хотел визуализировать все вместе. Не уверен, действительно ли это вопрос SO или CR. Не могли бы вы отправить ответ на некоторые примеры этих структур данных? Последние два для меня новы. – T145