Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 30, средняя оценка - 4.77
sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
#1

Задача "Производители-Потребители", реализация с помощью Events и циклического буфера - C++

23.10.2011, 14:41. Просмотров 3932. Ответов 4
Метки нет (Все метки)

Доброго времени суток.

Написал программу для решения сабжевой задачи, с условиями 1 производитель, 1 потребитель.
Программа работает, потоки синхронизируются, тупиков не возникает.

Однако, условия поменялись и нужно изменить текст программы таким образом, что бы производителей было несколько, а потребитель один. Попытался реализовать такие условия, но не могу уместить в голове синхронизацию не только между производителем-потребителем, но и между производителями, что бы они делили буфер и не пытались туда писать одновременно.

В реализации этого условия и прошу помочь. Улучшения кода по первому условию так же приветствуется.

Ниже - текст программы с 1 производителем и 1 потребителем.
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <iostream>
#include <conio.h>
#include <windows.h>
 
using namespace std;
 
unsigned long uThrProdID1, uThrConsID;
 
HANDLE hEventWrite, hEventRead;
HANDLE hThrProd1, hThrCons;
void ProducerThread(char name[11]);
void ConsumerThread(void *pParams);
 
#define SIZE_BUF 25
 
int cycleBuf[SIZE_BUF];
int tail = 0;
int head = 0;
int count = 0;
 
void FlushBuf(void);
void PutChar(int sym);
int GetChar(void);
 
int main()
{
    FlushBuf();
 
    hEventWrite = CreateEvent(NULL, FALSE, FALSE, NULL);
    hEventRead = CreateEvent(NULL, FALSE, TRUE, NULL);
 
    hThrProd1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ProducerThread, "Producer 1", 0, &uThrProdID1);
 
    hThrCons = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ConsumerThread, NULL, 0, &uThrConsID);
 
    getch();
    return 0;
}
 
void ProducerThread(char name[11])
{
    WaitForSingleObject(hEventRead, INFINITE);
    while(1)
    {
        Sleep(rand()%500);
 
        while (count < SIZE_BUF)
            PutChar(rand());
 
        cout <<  name << ": There are " << count << " symbols in buf" << endl << endl;
        SetEvent(hEventWrite);
    }
}
 
void ConsumerThread(void *pParams)
{
    WaitForSingleObject(hEventWrite, INFINITE);
    while(1)
    {
        Sleep(rand()%50);
 
        if (count == 0)
        {
            SetEvent(hEventRead);
            WaitForSingleObject(hEventWrite, INFINITE);
        }
 
        GetChar();
        cout << "Consumer: There are " << count << " symbols in buf now." << endl << endl;
    }
}
 
void FlushBuf(void)
{
    tail = 0;
    head = 0;
    count = 0;
}
 
void PutChar(int sym)
{
    if (count < SIZE_BUF)
    {
        cycleBuf[tail] = sym;
        count++;
        tail++;
        if (tail == SIZE_BUF) tail = 0;
    }
}
 
int GetChar(void)
{
    int sym = 0;
    if (count > 0)
    {
        sym = cycleBuf[head];
        count--;
        head++;
        if (head == SIZE_BUF) head = 0;
    }
    return sym;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.10.2011, 14:41
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Задача "Производители-Потребители", реализация с помощью Events и циклического буфера (C++):

Необработанное исключение в "0x77913ab3" в "x": 0xC0000005: Нарушение прав доступа при чтении "0xdddddddd" - C++
вот код, нужно найти 3 минимальных положительных числа в массиве. При размере массива больше 950 в конце заполнения рандомным способом...

Олимпиадная задача, "ЕГЭ". - C++
С целью упрощения ЕГЭ по литературе, было решено оставить в нем вопросы только с ответами &quot;да&quot; или &quot;нет&quot;. Бланк ответов представляет...

Решить прикладную задачу с помощью циклического вычислительного процесса - C++
Помогите решить...Не знаю как... Решить прикладную задачу с помощью циклического вычислительного процесса. Дано натуральное n....

Найти в строке последовательность символов ("abcd") и заменить ее другой ("xyz") - C++
Найти в строке последовательность символов (&quot;abcd&quot;) и заменить ее другой (&quot;xyz&quot;).

О "нестабильности" или "переполнении" цикла foreach - C++
Здравствуйте, коллеги. Недавно коллега-программист сообщил мне страшную вещь: оказывается, что цикл foreach может переполниться при...

Ошибка: invalid conversion from "int" to "SDL_RendererFlip" - C++
Скриншот приложен, Вот страница, откуда я брал этот код Подскажите что делать

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
niXman
Эксперт C++
3134 / 1446 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
23.10.2011, 20:08 #2
Цитата Сообщение от sergeyotro Посмотреть сообщение
не могу уместить в голове синхронизацию не только между производителем-потребителем, но и между производителями
использую блокируемую очередь.
sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
23.10.2011, 22:28  [ТС] #3
Цитата Сообщение от niXman Посмотреть сообщение
использую блокируемую очередь.
Спасибо за подсказку. Надеюсь я её правильно понял.

Вот код изменённой программы, работает правильно. Надеюсь, кому-нибудь пригодится.
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <iostream>
#include <conio.h>
#include <windows.h>
#define MAX_PRODUCERS 6
#define SIZE_BUF 25
//#define READ_OUTPUT
 
using namespace std;
 
DWORD uThrProdID[MAX_PRODUCERS], uThrConsID;
 
HANDLE hEventWrite, hEventRead, hEventBuf;
HANDLE hThrProdArray[MAX_PRODUCERS], hThrCons;
 
void ProducerThread(char name[11]);
void ConsumerThread(void *pParams);
 
int cycleBuf[SIZE_BUF];
int tail = 0;
int head = 0;
int count = 0;
 
void FlushBuf(void);
void PutChar(int sym);
int GetChar(void);
 
FILE *fw;
 
#ifdef READ_OUTPUT
FILE *fr;
#endif
 
int main()
{
    fw = fopen("bufw.txt", "w");
#ifdef READ_OUTPUT
    fr = fopen("bufr.txt", "w");
#endif
    FlushBuf();
 
    hEventWrite = CreateEvent(NULL, FALSE, FALSE, NULL);
    hEventBuf = CreateEvent(NULL, FALSE, TRUE, NULL);
    hEventRead = CreateEvent(NULL, FALSE, TRUE, NULL);
 
    for ( int i = 0; i < MAX_PRODUCERS; i++ )
    {
        char* prod = new char[11];
        sprintf(prod, "Producer %d", i+1);
        hThrProdArray[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ProducerThread, prod, 0, &uThrProdID[i]);
    }
 
    hThrCons = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ConsumerThread, NULL, 0, &uThrConsID);
 
    getch();
 
    fclose(fw);
#ifdef READ_OUTPUT
    fclose(fr);
#endif
 
    CloseHandle(hEventBuf);
    CloseHandle(hEventRead);
    CloseHandle(hEventWrite);
 
    for ( int i = 0; i < MAX_PRODUCERS; i++ )
        CloseHandle(hThrProdArray[i]);
 
    CloseHandle(hThrCons);
    return 0;
}
 
void ProducerThread(char name[11])
{
    while(1)
    {
        WaitForSingleObject(hEventRead, INFINITE);
        Sleep(rand()%500);
        if (count < SIZE_BUF)
        {
            for ( int i = 0; i < 3; i++ )
            {
                PutChar(name[9]);
                putc(name[9], fw);
            }
            putc(13, fw);
        }
        cout <<  name << ": There are " << count << " symbols in buf" << endl << endl;
        SetEvent(hEventWrite);
    }
}
 
void ConsumerThread(void *pParams)
{
    WaitForSingleObject(hEventWrite, INFINITE);
    while(1)
    {
        Sleep(rand()%50);
        if (count == 0)
        {
            SetEvent(hEventRead);
            WaitForSingleObject(hEventWrite, INFINITE);
        }
#ifdef READ_OUTPUT
        putc(GetChar(), fr);
#else
        GetChar();
#endif
        cout << "Consumer: I've read one symbol. There are " << count << " symbols in buf now. " << endl << endl;
        SetEvent(hEventRead);
    }
}
 
void FlushBuf(void)
{
    tail = 0;
    head = 0;
    count = 0;
}
 
void PutChar(int sym)
{
    WaitForSingleObject(hEventBuf, INFINITE);
    if (count < SIZE_BUF)
    {
        cycleBuf[tail] = sym;
        count++;
        tail++;
        if (tail == SIZE_BUF) tail = 0;
    }
    SetEvent(hEventBuf);
}
 
int GetChar(void)
{
    int sym = 0;
    if (count > 0)
    {
        sym = cycleBuf[head];
        count--;
        head++;
        if (head == SIZE_BUF) head = 0;
    }
    return sym;
}
niXman
Эксперт C++
3134 / 1446 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
23.10.2011, 23:55 #4
Цитата Сообщение от sergeyotro Посмотреть сообщение
Надеюсь я её правильно понял.
ну почти... я имел ввиду написать обертку вокруг std::queue в которой push() и pop() защитить мьютексами.

твое решение тоже не плохое.
tanya234
Сообщений: n/a
08.04.2014, 18:51 #5
а в какой среде вы разрабатывали?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.04.2014, 18:51
Привет! Вот еще темы с ответами:

CString buff = "aaa" + "bbb" - C++
Хочется одним оператором конкатенировать несколько подстрок CString buff = &quot;aaa&quot; + &quot;bbb&quot; компилятор выдает error C2110: cannot add two...

Qt Creator. Все "за" и "против" - C++
Доброго времени суток, форумчане! Сегодня задался вопросом использования такой IDE, как Qt Creator. Суть темы заключается в том, что я...

MessageBox - чтобы вместо "Yes" и "No" показывало "Да" и "Нет" - C++ Builder
Доброе время суток, как переделать int Key= Application-&gt;MessageBox(L&quot;Text&quot;, L&quot;Caption&quot;, MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2); чтоб...

Шахматы: охарактеризовать положение белых с помощью слов: "мат", "шах", "пат", "обыкновенная позиция" - Pascal
у белых на доске остался только король , у черных - король, слон, конь. охарактеризовать положение белых с помощью слов : мат, шах, пат,...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
08.04.2014, 18:51
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru