Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.61/18: Рейтинг темы: голосов - 18, средняя оценка - 4.61
3 / 3 / 0
Регистрация: 03.06.2019
Сообщений: 64

Идиома "Производитель - потребитель"

15.03.2020, 22:38. Показов 3964. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый вечер всем. Продолжаю изучать многопоточное программирование в С++ и одновременно сталкиваться с миллионом проблем. В этот раз ситуация такая: нужно реализовать две функции - производителя и потребителя. Конкретнее - эти ф-и должны выполнять следующее:
1. Задача производителя - создавать элементы и добавлять их в вектор.
Имя и конструкция: static void producer(Data& data, size_t items);
Параметры: data - структура, содержащая данные о векторе, и служебные данные, позже будет ее код;
items - к-во элементов, которое будет произведено.

2. Задача потребителя - использовать элементы вектора, в данном случае просто выводить на экран последний элемент вектора и сразу же удалять его.
Имя и конструкция: static void consumer(Data& data);
Параметры: data - структура, содержащая данные о векторе, и служебные данные, позже будет ее код;

3. Ф-и должны выполняться параллельно и конкурентно.

Вот код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <tuple>
#include <condition_variable>
#include <vector>
#include <mutex>
#include <thread>
#include <chrono>
using namespace std;
 
typedef struct {
    vector <int> v;
    mutex& mtx;
    condition_variable& cv;
    bool finished;
}Data;
 
 
static void producer(Data& data, size_t items) {
    for (int i = 0; i != items; i++) {
        this_thread::sleep_for(1s);
        {
            lock_guard<mutex> lk{ data.mtx };
            data.v.push_back(i);
        }
        data.cv.notify_all();
    }
    //end of f-n
    {
        lock_guard<mutex> lk{ data.mtx };
        data.finished = true;
    }
    data.cv.notify_all();
}
 
static void consumer(Data& data) {
    while (!data.finished) {
        unique_lock<mutex> l{ data.mtx };
        data.cv.wait(l, [&]() mutable {return !data.v.empty() || data.finished; });
        while (!data.v.empty()) {
            cout << "Got " << *(data.v.end() - 1)
                << " from vector.";
            data.v.erase(data.v.end() - 1);
        }
    }
}
 
 
 
int main()
{
    vector<int> v;
    mutex mut;
    condition_variable cv;
    bool finished{ false };
    Data data{ v, mut, cv, finished };
    thread t1{ producer, data, 10 };
    thread t2{ consumer, data };
    t1.join();
    t2.join();
}
Проблема вот в чем. Компилятор при запуске ругает меня, и кидает не очень-то информативные ошибки, вот они все:
error C2672: 'std::invoke': no matching overloaded function found;
error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...) noexcept(<expr>)
После чего, компиляция, естественно, заваливается. С ошибок я понял только, что что-то не так с ф-ей std::invoke().
В чем дело, ребята? Почему ошибки, и как их исправить?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.03.2020, 22:38
Ответы с готовыми решениями:

Производитель потребитель
Задание: написать программу, в которой реализуется следующее: запись рандомного числа в массив, получение данного числа из массива и...

C++11 thread производитель-потребитель
Реализовал схему производитель-потребитель. Есть класс генератора последовательных целых чисел, ограниченных максимальным занчением, на...

Идиома copy-and-swap
Подскажите, как реализовать данный класс используя идиому copy-and-swap, в текущей реализации операция присваивания не обеспечивает...

5
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
15.03.2020, 22:46
Лучший ответ Сообщение было отмечено NuMeRiC_ как решение

Решение

Цитата Сообщение от NuMeRiC_ Посмотреть сообщение
C++
1
2
 thread t1{ producer, data, 10 };
 thread t2{ consumer, data };
C++
1
2
3
    
thread t1{ producer, std::ref(data), 10 };
thread t2{ consumer, std::ref(data) }
Многопоточное программирование не при чем.
Почитайте что-нибудь о передаче параметров в шаблоны, вывод типов шаблона и ссылки.
Можно здесь: "Эффективный и современный С++. 42 рекомендации по использованию C++11 и C++14"
И здесь: "Шаблоны C++. Справочник разработчика"
1
3 / 3 / 0
Регистрация: 03.06.2019
Сообщений: 64
15.03.2020, 22:48  [ТС]
Вот код с комментариями:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <tuple>
#include <condition_variable>
#include <vector>
#include <mutex>
#include <thread>
#include <chrono>
using namespace std;
 
typedef struct {
    vector <int> v;         
    mutex& mtx; //Мьютекс для блокировки доступа к вектору
    condition_variable& cv; //condition_variable для оповещения потребителя
    bool finished; //Для оповещения, что генерация успешно завершена
}Data;
 
 
static void producer(Data& data, size_t items) {
    for (int i = 0; i != items; i++) {
        this_thread::sleep_for(1s); //Эмулируем сложность генерации
        {
            lock_guard<mutex> lk{ data.mtx }; //Блокируем мьютекс
            data.v.push_back(i); //Забираем последний элемент
        }
        data.cv.notify_all(); //Оповещаем потребителя 
    }
    //end of f-n
    {
        lock_guard<mutex> lk{ data.mtx }; //Блокируем мьютекс
        data.finished = true; //Работа завершена
    }
    data.cv.notify_all(); //Оповещаем потребителя 
}
 
static void consumer(Data& data) {
    while (!data.finished) { //Если работа не завершена 
        unique_lock<mutex> l{ data.mtx }; //Блокируем мьютекс
        data.cv.wait(l, [&]() mutable {return !data.v.empty() || data.finished; }); //ждем метода notify_all()
        while (!data.v.empty()) {  //Если вектор не пуст
            cout << "Got " << *(data.v.end() - 1) 
                << " from vector."; //Выводим на экран последний элемент
            data.v.erase(data.v.end() - 1); //Удаляем его
        }
    }
}
 
 
 
int main()
{
    vector<int> v;
    mutex mut;
    condition_variable cv;
    bool finished{ false };
    Data data{ v, mut, cv, finished };
    thread t1{ producer, data, 10 };
    thread t2{ consumer, data };
    t1.join();
    t2.join();
}
0
3 / 3 / 0
Регистрация: 03.06.2019
Сообщений: 64
15.03.2020, 22:51  [ТС]
DrOffset, спасибо большое! И благодарность за литературу!
Можно спросить, вкратце, с чем связана проблема?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
15.03.2020, 23:06
Цитата Сообщение от NuMeRiC_ Посмотреть сообщение
Можно спросить, вкратце, с чем связана проблема?
Конкретно здесь - поток копирует переданное по значению. А ваша поточная функция принимает ссылку. Поэтому нужно явно указывать, что вы хотите, чтобы была именно ссылка, иначе он будет пытаться искать вариант функции с параметром-значением. Собственно ошибка как раз об этом говорит:
Цитата Сообщение от NuMeRiC_ Посмотреть сообщение
no matching overloaded function found
Добавлено через 1 минуту
https://en.cppreference.com/w/... ead/thread
3) Creates new std::thread object and associates it with a thread of execution. The new thread of execution starts executing
C++
1
2
std::invoke(decay_copy(std::forward<Function>(f)), 
            decay_copy(std::forward<Args>(args))...);
where decay_copy is defined as
C++
1
2
template <class T>
std::decay_t<T> decay_copy(T&& v) { return std::forward<T>(v); }
Добавлено через 58 секунд
NuMeRiC_, Далее, чтобы понять, что вообще происходит в цитате выше, вам и нужна вышеперечисленная литература.
1
3 / 3 / 0
Регистрация: 03.06.2019
Сообщений: 64
15.03.2020, 23:13  [ТС]
Еще раз спасибо, выручили! Берусь за учебу.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
15.03.2020, 23:13
Помогаю со студенческими работами здесь

Базовый класс и идиома RAII
Приветствую всех. Есть базовый абстрактный класс TAdapter, у которого два наследника: TSerialAdapter и TBluetoothAdapter. В приложении...

Erase-remove idiom: идиома tuple
#include &lt;tuple&gt; #include &lt;iostream&gt; #include &lt;vector&gt; #include &lt;ctime&gt; #include &lt;algorithm&gt; int main() { std::vector&lt;...

Программа производитель/потребитель
По книге Джонсон М. Харт &quot;Системное программирование в среде Windows&quot; есть пример этой программы, но он написан на C. Возникла проблема...

Потребитель- производитель
Помогите пожалуйста в написании программы под ubuntu 11.04 сама задача(описание): http://sdmitri.ru/Erzeuger-Verbraucher-Problem

Производитель и потребитель
Здравствуйте! Пожалуйста, помогите растолковать программу. У меня есть такое задание: Задача производитель-потребитель. Параллельные...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru