C/Visual C - programa en C que implemente el problema del productor/consumidor con 2 procesos

 
Vista:
Imágen de perfil de Juan José
Val: 15
Ha mantenido su posición en C/Visual C (en relación al último mes)
Gráfica de C/Visual C

programa en C que implemente el problema del productor/consumidor con 2 procesos

Publicado por Juan José (7 intervenciones) el 21/10/2020 13:13:54
Buenos dias/tardes/noches,

Estoy haciendo un ejercicio en C. Dejo el enunciado al completo a continuación:

Si alguien puede, me gustaría solucionarlo con ayuda, si puede ser realizando una videollamada o algo parecido me vendría genial. Yo soy residente en España.


Crear un programa en C que implemente el problema del productor/consumidor con 2 procesos independientes. Para ello, será necesario utilizar semáforos y memoria compartida. El Productor obtendrá los datos de contacto de diversas personas y se los enviará al Consumidor para que éste los muestre por pantalla. Para determinar el número de contactos a transferir, el Productor obtendrá dicha información por parámetros. Los datos de contacto están formados por la siguiente información:
• Apellido1
• Apellido2
• Nombre
• Email
• Telf. Móvil
El Productor creará una estructura (mediante struct) para almacenar los datos de un sólo contacto y almacenará dicha estructura en el buffer, el cuál será construido mediante memoria compartida. El buffer podrá almacenar simultáneamente hasta 5 contactos. El Consumidor obtendrá los datos de cada contacto del buffer y los mostrará por pantalla. Este proceso será iterativo hasta que se envíe todos los contactos. Tener en cuenta obligatoriamente los siguientes aspectos para implementar el código:
• Tanto el conjunto de los semáforos como la memoria compartida serán creados por el Consumidor.
• El Productor será el único proceso que obtiene el número de contactos a transferir por parámetro.
Nota: El Consumidor no tiene que saber cuantos contactos le enviará el Productor. Por tanto, para que el Consumidor pueda acabar su ejecución, el Productor tendrá que pasarle alguna información a éste. Pensad cómo resolver este problema.



Dejo el código del productor:
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
/* PROCESO PRODUCTOR */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#define KEY 100
#define MB 0      // ID del semáforo Manipulación del Buffer
#define EL 1       // ID del semáforo Espacio Libre
#define ED 2      // ID del semáforo Elemento Disponible
#define TAMBUFFER 5      // TAMaño del BUFFER
 
int main (argc, argv)
   int argc;
   char **argv; {
 
   /* Declaración de variables */
   int i;
   int numContactos;   /* número de contactos a visualizar */
   int semid;                /* ID al conjunto de semáforos */
   int shmid;                /* ID a la memoria compartida para almacenar el buffer */
 
   struct DatosContacto {
      Aquí vienen declarados todos los datos de un contacto
   } contacto, *addr;   /* contacto se utiliza para almacenar los datos de un contacto */
                                 /* *addr es un puntero a la memoria compartida */
 
   struct sembuf sem_oper;  /* Para las operaciones wait y signal con semáforos */
 
   /* Determinar el número de contactos a producir */
   Aquí viene el código que determina el número de contactos
 
   /* Acceder a un conjunto de 3 semáforos ya existente */
   semid=semget(KEY, 3, 0770);
   if (semid == -1) {
      printf(\nError en el acceso al conjunto de semáforos”);
      exit(1);  /* Error 1: error en el acceso al conjunto de semáforos */
   }
 
   /* OJO: No hay que inicializar los semáforos. Lo ha hecho el proceso Consumidor */
 
   /* Acceder a la memoria compartida */
  shmid = shmget(KEY, calcular el tamaño, 0770);
  if (shmid == -1) {
    printf(\nError en la creación de la Memoria compartida”);
    exit(2);  /* Error 2: error al crear la Memoria compartida */
  }
 
  /* Enlazar la memoria compartida al proceso */
  addr = shmat(shmid, 0, 0);
   /* Pasarle al Consumidor el número de contactos que se va a producer */
    Aquí viene el código para indicarle al consumidor cuantos contactos tiene que consumir
 
   /* Repetir para cada contacto /*/
   for (i=0; i<numContactos; i++) {
       /* Producir elemento */
       Aquí viene el código de producir un elemento
 
      /* Wait (Espacio libre) */
      sem_oper.sem_num = EL; /* Seleccionamos semáforo Espacio Libre */
      sem_oper.sem_op = -1; /* Decrementar 1 (hace un wait) */
      sem_oper.sem_flg = SEM_UNDO;  /* Para evitar interbloqueos si
                                                                un proceso acaba inesperadamente */
      semop (semid, &sem_oper, 1);
 
      /* Wait (Manipulación del buffer) */
      sem_oper.sem_num = MB;
      sem_oper.sem_op = -1;
      sem_oper.sem_flg = SEM_UNDO;  /* No es necesario porque ya
                                                                 se ha hecho anteriormente */
      semop (semid, &sem_oper, 1);
 
      /* Sección crítica: Para acceder al buffer que será el recurso no compartible */
      Aqui viene el código de la sección crítica del productor
 
 
       /* Signal (Manipulación del buffer) */
       sem_oper.sem_num = MB;
       sem_oper.sem_op = 1;
       semop (semid, &sem_oper, 1);
 
       /* Signal (Elemento Disponible) */
       sem_oper.sem_num = ED;
       sem_oper.sem_op = 1;
       semop (semid, &sem_oper, 1);
 
   }  /* fin de for */
 
   /* Separamos la memoria compartida del proceso */
   shmdt(addr);
 
   return 0;
}  /* fin de main */

Y del consumidor:
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
/* PROCESO CONSUMIDOR */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <string.h>
#define KEY 100
#define MB 0      // ID del semáforo Manipulación del Buffer
#define EL 1       // ID del semáforo Espacio Libre
#define ED 2      // ID del semáforo Elemento Disponible
#define TAMBUFFER 5      // TAMaño del BUFFER
 
int main () {
   /* Declaración de variables */
   int i;
   int numContactos;   /* número de contactos a visualizar */
   int semid;  /* ID al conjunto de semáforos */
   int shmid;  /* ID a la memoria compartida para almacenar el buffer */
 
   struct DatosContacto {
      Aquí vienen declarados todos los datos de un contacto
   } contacto, *addr;   /* contacto se utiliza para almacenar los datos de un contacto */
                                   /* *addr es un puntero a la memoria compartida */
 
  struct sembuf sem_oper;  /* Para las operaciones wait y signal con semáforos */
  union semun {
int val;
struct semid_ds *semstat;
unsigned short *array;
  } arg;
 
  /* Creamos un conjunto de 3 semáforos */
  semid=semget(KEY, 3, 0770 | IPC_CREAT);
  if (semid == -1) {
     printf(\nError en la creación de los semáforos”);
     exit(1);  /* Error 1: error en la creación de semáforos */
  }
 
  /* Inicializamos los semáforos */
  arg.array = (unsigned short *) malloc (sizeof (short)*3);
  arg.array[MB] = 1;
  arg.array[EL] = TAMBUFFER;
  arg.array[ED] = 0;
  semctl (semid, 3, SETALL, arg);
 
   /* Crear la memoria compartida */
  shmid = shmget(KEY, calcular el tamaño, 0770 | IPC_CREAT);
  if (shmid == -1) {
    printf(\nError en la creación de la Memoria compartida”);
    exit(2);  /* Error 2: error al crear la Memoria compartida */
  }
 
  /* Enlazar la memoria compartida al proceso */
  addr = shmat(shmid, 0, 0);
 
   /* Determinar el número de contactos a obtener */
   Aquí viene el código que determina el número de contactos
 
   /* Repetir para cada contacto obtenido del productor */
   for (i=0; i<numContactos; i++) {
      /* Wait (Elemento disponible) */
      sem_oper.sem_num = ED; /* Seleccionamos semáforo Elemento Disponible */
      sem_oper.sem_op = -1; /* Decrementar 1 (hace un wait) */
      sem_oper.sem_flg = SEM_UNDO;  /* Para evitar interbloqueos si
                                                                 un proceso acaba inesperadamente */
      semop (semid, &sem_oper, 1);
 
      /* Wait (Manipulación del buffer) */
      sem_oper.sem_num = MB;
      sem_oper.sem_op = -1;
      sem_oper.sem_flg = SEM_UNDO;  /* No es necesario porque ya
                                                                 se ha hecho anteriormente */
      semop (semid, &sem_oper, 1);
 
      /* Sección crítica: Para acceder al buffer que será el recurso no compartible */
      Aqui viene el código de la sección crítica del consumidor
 
 
      /* Signal (Manipulación del buffer) */
      sem_oper.sem_num = MB;
      sem_oper.sem_op = 1;
      semop (semid, &sem_oper, 1);
 
      /* Signal (Espacio libre) */
      sem_oper.sem_num = EL;
      sem_oper.sem_op = 1;
      semop (semid, &sem_oper, 1);
 
      /* Consumir el elemento */
      Aquí viene el código de Consumir el elemento
 
   }  /* fin de for */
 
   /* Eliminamos el conjunto de semáforos */
   semctl (semid, 3, IPC_RMID, 0);
 
   /* Separamos la memoria compartida del proceso */
   shmdt(addr);
 
   /* Eliminamos la memoria compartida */
   /* Esta operación lo realiza uno de los procesos */
   shmctl(shmid, IPC_RMID, 0);
 
   /* liberamos la memoria dinámica */
   free (arg.array);
 
   return 0;
}  /* fin de main */
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

programa en C que implemente el problema del productor/consumidor con 2 procesos

Publicado por Nacho (76 intervenciones) el 21/10/2020 13:33:28
Muy chulos esos tipos de programas. ¿Tienes algún problema con algo en concreto?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
Imágen de perfil de Juan José
Val: 15
Ha mantenido su posición en C/Visual C (en relación al último mes)
Gráfica de C/Visual C

programa en C que implemente el problema del productor/consumidor con 2 procesos

Publicado por Juan José (7 intervenciones) el 21/10/2020 13:50:35
No entiendo muy bien el ejercicio en sí. Principalmente, es la segunda o tercera vez que toco C y me cuesta un poco.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

programa en C que implemente el problema del productor/consumidor con 2 procesos

Publicado por Nacho (76 intervenciones) el 21/10/2020 14:47:13
Se parte de una estructura de datos
1
2
3
4
5
6
7
8
struct Contactos
{
    char Apellido1[20];
    char Apellido2[20];
    char Nombre[20];
    char Email[20];
    char TelfMóvil[9];
};

Se reserva un bloque de memoria con shmget, en linux, con tamaño de la estructura *5, pues quiere que haya 5 contactos como máximo.

El enunciado no me parece correcto.Cuando se usa memoria compartida no se mandan datos. Para que el consumidor sepa que ya puede acceder a los datos lo que hace el productor es soltar el bloque de datos. Como el consumidor intenta acceder a los datos y no puede se queda suspendido hasta que el productor los suelte. Eso se hace con un semáforo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Rodrigo
Val: 350
Bronce
Ha mantenido su posición en C/Visual C (en relación al último mes)
Gráfica de C/Visual C

programa en C que implemente el problema del productor/consumidor con 2 procesos

Publicado por Rodrigo (119 intervenciones) el 21/10/2020 16:47:26
Otras 2 restricciones o condiciones que existen en este problema es que
- el productor deja de producir si ya no hay espacio para producir 1 elemento mas
- el consumidor se detiene (ya no consume) cuando se acabaron los productos para consumir.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar