Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.56/27: Рейтинг темы: голосов - 27, средняя оценка - 4.56
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
1

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

23.10.2011, 14:41. Просмотров 5603. Ответов 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;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.10.2011, 14:41
Ответы с готовыми решениями:

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

С помощью функции реализовать сравнение двух целых чисел (вернуть результат ">", "<" или "=")
vint-81, а может сможешь помочь мне в этом : С помощью функции реализовать сравнение двух ...

Чем "угощают" нас производители табачной продукции
eo_CffY4NPM

Как написать регулярное выражение для выдергивания английских букв и символов: "+", ",", ":", "-", " ", "!", "?" и "."
Не могу ни как собразить как написать регулярное выражение для выдергивания английских букв и...

4
Эксперт С++
3210 / 1458 / 73
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
23.10.2011, 20:08 2
Цитата Сообщение от sergeyotro Посмотреть сообщение
не могу уместить в голове синхронизацию не только между производителем-потребителем, но и между производителями
использую блокируемую очередь.
1
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;
}
0
Эксперт С++
3210 / 1458 / 73
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
23.10.2011, 23:55 4
Цитата Сообщение от sergeyotro Посмотреть сообщение
Надеюсь я её правильно понял.
ну почти... я имел ввиду написать обертку вокруг std::queue в которой push() и pop() защитить мьютексами.

твое решение тоже не плохое.
0
tanya234
08.04.2014, 18:51 5
а в какой среде вы разрабатывали?
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.04.2014, 18:51

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

Даны три слова - "мама", "мыла", "раму". Задача - напечатать всевозможные варианты построения слов
Я записал код, однако эту часть надо автоматизировать, поможете? КОД: } #include &lt;iostream&gt;...

Необработанное исключение в "0x76f015de" в "контрольная 1 задача 2.exe": 0xC0000005: Нарушение прав доступа при чтении "0x334e2c64"
доброго времени суток. Необработанное исключение в &quot;0x76f015de&quot; в &quot;контрольная 1 задача 2.exe&quot;:...

В зависимости от времени года "весна", "лето", "осень", "зима" определить погоду "тепло", "жарко", "холодно", "очень холодно"
В зависимости от времени года &quot;весна&quot;, &quot;лето&quot;, &quot;осень&quot;, &quot;зима&quot; определить погоду &quot;тепло&quot;,...

Приложение, содержащее поле со списком (задача "Молоко", "Кефир", "Сметана")
Приложение, содержащее поле со списком, текстовое поле и три кнопки. Первоначально поле со списком...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

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