Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
3 / 3 / 1
Регистрация: 25.12.2014
Сообщений: 63

Производители и потребители

16.05.2016, 13:55. Показов 1983. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток.
Стоит задача производителей и потребителей на основе механизма обмена сообщениями.
Буфер сообщений должен быть ограничен.

Проблема в том, что требуется замоделировать три ситуации:
1) производитель и потребитель работают с одной скоростью;
2) производитель быстрее потребителя;
3) потребитель быстрее производителя.

Для всего это я в RAD Studio сделал вот что:
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <vcl.h>
#include <windows.h>
#include <iostream.h>
#include <fstream.h>
#pragma hdrstop
 
#include "Unit1.h"
char* path = new char[12];
HANDLE hWrite,hRead,hProducer,hConsumer;//дескрипторы событий и нитей
int buffer = 0,BUFFER_SIZE,PROD_SPEED,CONS_SPEED;//переменные числа сообщений в буфере, размера, скоростей
 
//для ведения логов
TDateTime df;
ofstream logthread;
 
void Producer();//заголовок функции производителя
void Consumer();//залоговок функции потребителя
void SendMess(){::buffer++;}//добавить сообщение
void ReadMess(){::buffer--;}//прочитать сообщение
 
void ProducerConsumer(int BUFFER_SIZE, int PROD_SPEED, int CONS_SPEED){//основная функция
    unsigned long uProducer, uConsumer;//для создания потока
 
    //инициализация глобальных переменных
    ::BUFFER_SIZE=BUFFER_SIZE;
    ::CONS_SPEED = CONS_SPEED;
    ::PROD_SPEED = PROD_SPEED;
    HANDLE hWrite = CreateEvent(NULL, FALSE, FALSE, NULL),//событие записи
           hRead = CreateEvent(NULL, FALSE, TRUE, NULL);//событие чтения
 
    //создание потоков
    HANDLE hProducer = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Producer, NULL, 0, &uProducer),
           hConsumer = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Consumer, NULL, 0, &uConsumer);
}
 
void Producer(){
    logthread.open(path, ios::app);
    AnsiString time = FormatDateTime("h:mm:ss",df.CurrentDateTime());
    logthread<<(time+" Поток 1 запущен \n").c_str();
    logthread.close();
    Form1->log->Lines->Add(time+" Поток 1 запущен \n");
    Form1->log->Update();
    WaitForSingleObject(hRead, INFINITE);
    while(1)
    {
        Sleep(rand()%PROD_SPEED);
        while (::buffer < ::BUFFER_SIZE){
            SendMess();
            Form1->log->Lines->Add(time+" В буфер добавлено ещё сообщение. Теперь их -"+ IntToStr(buffer) +" \n");
            Form1->log->Update();
            Sleep(rand()%PROD_SPEED);
        }
        SetEvent(hWrite);
    }
}
void Consumer()
{
    WaitForSingleObject(hWrite, INFINITE);
    while(1)
    {
        Sleep(rand()%CONS_SPEED);
        if (buffer == 0)
        {
            SetEvent(hRead);
            WaitForSingleObject(hWrite, INFINITE);
        }
        ReadMess();
    }
}
 
void __fastcall TForm1::startClick(TObject *Sender)//запускающая действо кнопка
{
int i = menu->ItemIndex;
    if(i==-1){
        ShowMessage("Пункт меню не выбран");
        return;
    }
    switch(i){
...
        case 5:{
            int buffersize = StrToInt(Edit1->Text),
            producerspeed = StrToInt(Edit2->Text),
            consumerspeed = StrToInt(Edit3->Text);
        ProducerConsumer(buffersize,producerspeed,consumerspeed);
        break;
        }
    }
}
Скорости вводятся ручками в Edit-ы. Как и размер буфера.
Посыл нового сообщения в буфер = инкремент глобальной переменной buffer.
Прочтение сообщения = её декремент.
Проблема следующая: в ходе работы программы, в функции Producer() игнорируется то, что написано в условии цикла, то есть вот что:

C++
1
2
3
4
5
6
    while (::buffer < ::BUFFER_SIZE){//это условие игнорируется
            SendMess();
            Form1->log->Lines->Add(time+" В буфер добавлено ещё сообщение. Теперь их -"+ IntToStr(buffer) +" \n");
            Form1->log->Update();
            Sleep(rand()%PROD_SPEED);
        }
То есть число buffer влёгкую превышает максимальный размер!

В попытках решить эту проблему я убрал Sleep внутри цикла с игнорируемым условием.
Это помогло: размер перестал превышаться.
Однако, задача тогда не решена!
Поэтому я вернул все как было и решил проверить по-другому: создал кнопку button2, запускающую один поток
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void __fastcall TForm1::Button2Click(TObject *Sender)
{
unsigned long uProducer, uConsumer;//для создания потока
 
    //инициализация глобальных переменных
    ::BUFFER_SIZE=StrToInt(Edit1->Text);
    ::CONS_SPEED = StrToInt(Edit2->Text);
    ::PROD_SPEED = StrToInt(Edit3->Text);
    HANDLE hWrite = CreateEvent(NULL, FALSE, FALSE, NULL),//событие записи
           hRead = CreateEvent(NULL, FALSE, TRUE, NULL);//событие чтения
 
    //создание потоков
    HANDLE hProducer = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Producer, NULL, 0, &uProducer);
}
Теперь уже, несмотря на задержку, размер буфера не превышается.

Не понимаю, что происходит.

Может быть, кто-нибудь подскажет, как решить проблему с задержкой и превышением буфера?
Спасибо заранее всем, кто откликнется.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
16.05.2016, 13:55
Ответы с готовыми решениями:

Задача "Производители-Потребители", реализация с помощью Events и циклического буфера
Доброго времени суток. Написал программу для решения сабжевой задачи, с условиями 1 производитель, 1 потребитель. Программа...

Создание запроса бд Договора и потребители
Всем привет. В базе есть три таблицы. Потребители заключившие договора лицевой потребителя адрес список всех...

Потребители сдали в ремонт 16 компьютеров
Потребители сдали в ремонт 16 компьютеров. Из них 8 нуждаются в мелком ремонте. Мастер берет 6 компьютеров. Какова вероятность того,...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
16.05.2016, 13:55
Помогаю со студенческими работами здесь

Украинцы - ничем не сдерживаемые потребители
Излишнее увлечение украинцев покупкой дорогих вещей при низком уровне производительности труда приводит к постоянной неудовлетворенности...

БП — Энергопотребление компа (un-, mounted volumes, потребители, монитор…)
Для чего существует mount-ировка и unmount-ировка? Чему соответствует unmounted режим диска - выключен? спящий режим? включен? - с точки...

Производители кондиционеров vs производители кондиционеров
Мне интересно было бы с Вами обсудить Ваши предпочтения и какая фирма надежнее на Ваш взгляд, почему именно ей и отдаете предпочтения? Так...

Производители термопотов
Привет! Подскажите, если не трудно – мама заказала себе на день рождение термопот. Как я понял из ее объяснений – это симбиоз...

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


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

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru