El problema productor-consumidor es un ejemplo de un problema de sincronización de procesos múltiples . El problema describe dos procesos, el productor y el consumidor que comparten un búfer común de tamaño fijo y lo usan como una cola .
- El trabajo del productor es generar datos, ponerlos en el búfer y comenzar de nuevo.
- Al mismo tiempo, el consumidor consume los datos (es decir, los elimina del búfer), una pieza a la vez.
Problema: dado el búfer común de tamaño fijo, la tarea es asegurarse de que el productor no pueda agregar datos al búfer cuando esté lleno y el consumidor no pueda eliminar datos de un búfer vacío.
Solución: el productor debe ir a dormir o descartar datos si el búfer está lleno. La próxima vez que el consumidor retire un artículo del búfer, notifica al productor, quien comienza a llenar el búfer nuevamente. De la misma manera, el consumidor puede irse a dormir si encuentra que el búfer está vacío. La próxima vez que el productor pone datos en el búfer, despierta al consumidor dormido.
Nota: Una solución inadecuada podría resultar en un interbloqueo en el que ambos procesos esperan ser activados.
Planteamiento: La idea es utilizar el concepto de programación paralela y Sección Crítica para implementar el problema Productor-Consumidor en lenguaje C usando OpenMP .
A continuación se muestra la implementación del enfoque anterior:
C
// C program for the above approach #include <stdio.h> #include <stdlib.h> // Initialize a mutex to 1 int mutex = 1; // Number of full slots as 0 int full = 0; // Number of empty slots as size // of buffer int empty = 10, x = 0; // Function to produce an item and // add it to the buffer void producer() { // Decrease mutex value by 1 --mutex; // Increase the number of full // slots by 1 ++full; // Decrease the number of empty // slots by 1 --empty; // Item produced x++; printf("\nProducer produces" "item %d", x); // Increase mutex value by 1 ++mutex; } // Function to consume an item and // remove it from buffer void consumer() { // Decrease mutex value by 1 --mutex; // Decrease the number of full // slots by 1 --full; // Increase the number of empty // slots by 1 ++empty; printf("\nConsumer consumes " "item %d", x); x--; // Increase mutex value by 1 ++mutex; } // Driver Code int main() { int n, i; printf("\n1. Press 1 for Producer" "\n2. Press 2 for Consumer" "\n3. Press 3 for Exit"); // Using '#pragma omp parallel for' // can give wrong value due to // synchronization issues. // 'critical' specifies that code is // executed by only one thread at a // time i.e., only one thread enters // the critical section at a given time #pragma omp critical for (i = 1; i > 0; i++) { printf("\nEnter your choice:"); scanf("%d", &n); // Switch Cases switch (n) { case 1: // If mutex is 1 and empty // is non-zero, then it is // possible to produce if ((mutex == 1) && (empty != 0)) { producer(); } // Otherwise, print buffer // is full else { printf("Buffer is full!"); } break; case 2: // If mutex is 1 and full // is non-zero, then it is // possible to consume if ((mutex == 1) && (full != 0)) { consumer(); } // Otherwise, print Buffer // is empty else { printf("Buffer is empty!"); } break; // Exit Condition case 3: exit(0); break; } } }
Producción:
Publicación traducida automáticamente
Artículo escrito por SAKSHIKULSHRESHTHA y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA