-
Notifications
You must be signed in to change notification settings - Fork 0
/
prodcons-lifo.cpp
128 lines (104 loc) · 4.04 KB
/
prodcons-lifo.cpp
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
// Compilación: g++ -std=c++11 -pthread -I. -o prod-cons-lifo prodcons-lifo.cpp Semaphore.cpp
#include <iostream>
#include <cassert>
#include <thread>
#include <mutex>
#include <random>
#include "Semaphore.h"
using namespace std ;
using namespace SEM ;
//**********************************************************************
// variables compartidas
const int num_items = 40 , // número de items
tam_vec = 10 ; // tamaño del buffer
unsigned cont_prod[num_items] = {0}, // contadores de verificación: producidos
cont_cons[num_items] = {0}; // contadores de verificación: consumidos
unsigned vec[tam_vec],
pos = 0;
Semaphore libres = tam_vec,
ocupadas = 0,
acceder_buffer = 1;
//**********************************************************************
// plantilla de función para generar un entero aleatorio uniformemente
// distribuido entre dos valores enteros, ambos incluidos
// (ambos tienen que ser dos constantes, conocidas en tiempo de compilación)
//----------------------------------------------------------------------
template< int min, int max > int aleatorio()
{
static default_random_engine generador( ( random_device() )() );
static uniform_int_distribution<int> distribucion_uniforme( min, max ) ;
return distribucion_uniforme( generador );
}
//**********************************************************************
// funciones comunes a las dos soluciones (fifo y lifo)
//----------------------------------------------------------------------
int producir_dato() {
static int contador = 0 ;
// Realizar esperas aleatoria entre 20 y 100 milisegundos
this_thread::sleep_for( chrono::milliseconds( aleatorio<20,100>() ));
cout << "producido: " << contador << endl << flush ;
cont_prod[contador] ++ ;
return contador++ ;
}
//----------------------------------------------------------------------
void consumir_dato( unsigned dato ) {
assert( dato < num_items );
cont_cons[dato] ++ ;
this_thread::sleep_for( chrono::milliseconds( aleatorio<20,100>() ));
cout << " consumido: " << dato << endl ;
}
//----------------------------------------------------------------------
void test_contadores() {
bool ok = true ;
cout << "comprobando contadores ...." ;
for( unsigned i = 0 ; i < num_items ; i++ ) {
if ( cont_prod[i] != 1 ) {
cout << "error: valor " << i << " producido " << cont_prod[i] << " veces." << endl ;
ok = false ;
}
if ( cont_cons[i] != 1 ) {
cout << "error: valor " << i << " consumido " << cont_cons[i] << " veces" << endl ;
ok = false ;
}
}
if (ok)
cout << endl << flush << "solución (aparentemente) correcta." << endl << flush ;
}
//----------------------------------------------------------------------
void funcion_hebra_productora( ) {
for( unsigned i = 0 ; i < num_items ; i++ ) {
int dato = producir_dato() ;
sem_wait( libres );
sem_wait( acceder_buffer );
vec[pos] = dato;
pos++;
cout << "escrito: " << dato << endl;
sem_signal( acceder_buffer );
sem_signal( ocupadas );
}
}
//----------------------------------------------------------------------
void funcion_hebra_consumidora( ) {
for( unsigned i = 0 ; i < num_items ; i++ ) {
sem_wait ( ocupadas );
sem_wait( acceder_buffer );
pos--;
int dato = vec[pos];
cout << " leido: " << dato << endl;
sem_signal( acceder_buffer );
sem_signal ( libres );
consumir_dato( dato ) ;
}
}
//----------------------------------------------------------------------
int main() {
cout << "--------------------------------------------------------" << endl
<< "Problema de los productores-consumidores (solución LIFO)." << endl
<< "--------------------------------------------------------" << endl
<< flush ;
thread hebra_productora ( funcion_hebra_productora ),
hebra_consumidora( funcion_hebra_consumidora );
hebra_productora.join() ;
hebra_consumidora.join() ;
test_contadores();
}