Maison  >  Article  >  développement back-end  >  Traduction du problème producteur-consommateur en langage C

Traduction du problème producteur-consommateur en langage C

王林
王林avant
2023-09-09 08:17:04690parcourir

Traduction du problème producteur-consommateur en langage C

En programmation concurrente, la concurrence représente un concept clé nécessaire pour bien comprendre le fonctionnement de ces systèmes. Parmi les différents défis auxquels sont confrontés les praticiens travaillant avec ces systèmes, le problème producteur-consommateur est l'un des problèmes de synchronisation les plus connus. Dans cet article, nous visons à analyser ce sujet et à souligner son importance pour le calcul simultané, tout en explorant également les solutions possibles basées sur C.

La traduction chinoise de

Introduction

est :

Introduction

Dans un système concurrent, plusieurs threads ou processus peuvent accéder aux ressources partagées en même temps. Le problème producteur-consommateur implique deux entités : le producteur génère des données ou des tâches, et le consommateur traite ou consomme les données générées. Le défi est de garantir que les producteurs et les consommateurs synchronisent leurs activités pour éviter des problèmes tels que des conditions de concurrence ou des conflits de ressources.

Comprendre le problème producteur-consommateur

Énoncé du problème

Une définition possible du problème producteur-consommateur implique deux groupes principaux : les producteurs de données stockent leur travail dans un espace partagé appelé tampon, et les processeurs (consommateurs) utilisent le contenu des données enregistrées dans cet espace. Ces personnes utilisent leur expertise pour rassembler des éléments dans ce scénario de stockage temporaire, les analysent de manière approfondie, puis fournissent des résultats perspicaces.

Exigences de synchronisation

Résoudre le dilemme producteur-consommateur passe nécessairement par la mise en œuvre de technologies de collaboration synchronisées entre les différentes parties prenantes. L’optimisation de l’intégration des protocoles de synchronisation est cruciale afin d’éviter que les tampons des appareils ne soient surchargés par les unités productrices ou épuisés par les unités consommatrices.

Implémentation du problème producteur-consommateur en langage C

Tampon partagé

En langage C, un tampon partagé peut être implémenté à l'aide d'une structure de données de tableau ou de file d'attente. Les tampons doivent être de taille fixe et prendre en charge des opérations telles que l'ajout de données (producteur) et la récupération de données (consommateur).

Technologie de synchronisation

Une variété de techniques de synchronisation peuvent être utilisées pour résoudre le problème producteur-consommateur en C, notamment

  • Verrous mutex et variables de condition - Les verrous mutex offrent une protection d'exclusion mutuelle pour les parties critiques du code, tandis que les variables de condition permettent aux threads d'attendre qu'une condition spécifique soit remplie.

  • Semaphores - Les sémaphores peuvent contrôler l'accès aux tampons partagés en suivant le nombre d'emplacements vides et pleins.

  • Moniteurs - Les moniteurs fournissent un niveau d'abstraction supérieur pour la synchronisation et encapsulent les données partagées et les opérations qui peuvent y être effectuées.

Solution au problème producteur-consommateur en C

Solution tampon délimitée

Une solution courante au problème producteur-consommateur est la solution tampon limitée. Il s’agit d’utiliser des tampons de taille fixe avec un mécanisme de synchronisation pour garantir que les producteurs et les consommateurs coopèrent correctement. La capacité de production d'un projet est limitée par la taille de la zone tampon, la planification doit donc tenir compte de cette spécification pour éviter de dépasser l'espace disponible dans la zone tampon.

Fils de producteurs et de consommateurs

En langage C, les activités du producteur et du consommateur peuvent être implémentées sous forme de threads distincts. Chaque thread producteur génère des données et les ajoute au tampon partagé, tandis que chaque thread consommateur récupère les données du tampon et les traite. Les mécanismes de synchronisation sont utilisés pour coordonner les activités des threads.

Gestion des cas extrêmes

Dans des scénarios réels, des facteurs supplémentaires peuvent devoir être pris en compte. Par exemple, si un producteur génère des données à un rythme plus rapide qu'un consommateur ne peut les traiter, vous devrez peut-être utiliser des mécanismes de mise en mémoire tampon tels que le blocage ou la suppression des données pour éviter la perte de données ou les situations de blocage.

Deux exemples de codes écrits en langage C pour illustrer la mise en œuvre du problème producteur-consommateur

Solution tampon délimitée utilisant un mutex et une variable de condition, avec condition de fin.

La traduction chinoise de

Exemple

est :

Exemple

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define BUFFER_SIZE 5
#define MAX_ITEMS 5

int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
int produced_count = 0;
int consumed_count = 0;

pthread_mutex_t mutex;
pthread_cond_t full;
pthread_cond_t empty;

void* producer(void* arg) {
   int item = 1;

   while (produced_count < MAX_ITEMS) {
      pthread_mutex_lock(&mutex);

      while (((in + 1) % BUFFER_SIZE) == out) {
         pthread_cond_wait(&empty, &mutex);
      }

      buffer[in] = item;
      printf("Produced: %d</p><p>", item);
      item++;
      in = (in + 1) % BUFFER_SIZE;

      produced_count++;

      pthread_cond_signal(&full);
      pthread_mutex_unlock(&mutex);
   }

   pthread_exit(NULL);
}

void* consumer(void* arg) {
   while (consumed_count < MAX_ITEMS) {
      pthread_mutex_lock(&mutex);

      while (in == out) {
         pthread_cond_wait(&full, &mutex);
      }

      int item = buffer[out];
      printf("Consumed: %d</p><p>", item);
      out = (out + 1) % BUFFER_SIZE;

      consumed_count++;

      pthread_cond_signal(&empty);
      pthread_mutex_unlock(&mutex);
   }

   pthread_exit(NULL);
}

int main() {
   pthread_t producerThread, consumerThread;

   pthread_mutex_init(&mutex, NULL);
   pthread_cond_init(&full, NULL);
   pthread_cond_init(&empty, NULL);

   pthread_create(&producerThread, NULL, producer, NULL);
   pthread_create(&consumerThread, NULL, consumer, NULL);

   pthread_join(producerThread, NULL);
   pthread_join(consumerThread, NULL);

   pthread_mutex_destroy(&mutex);
   pthread_cond_destroy(&full);
   pthread_cond_destroy(&empty);

   return 0;
}

Dans cet exemple, une solution tampon limitée au problème producteur-consommateur est implémentée à l'aide d'un mutex et de variables de condition. Les threads producteurs génèrent des éléments et les ajoutent au tampon, tandis que les threads consommateurs récupèrent et consomment les éléments du tampon. Le mutex garantit une exclusivité mutuelle lors de l'accès au tampon, et les variables de condition (pleines et vides) coordonnent les threads producteur et consommateur. Ajout de conditions de résiliation pour limiter le nombre d'éléments générés et consommés.

Sortie

Produced: 1
Produced: 2
Produced: 3
Produced: 4
Consumed: 1
Consumed: 2
Consumed: 3
Consumed: 4
Produced: 5
Consumed: 5

Solution tampon délimitée utilisant des sémaphores et des conditions de terminaison

La traduction chinoise de

Exemple

est :

Exemple

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

#define BUFFER_SIZE 5
#define MAX_ITEMS 20

int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
int produced_count = 0;
int consumed_count = 0;

sem_t mutex;
sem_t full;
sem_t empty;

void* producer(void* arg) {
   int item = 1;

   while (produced_count < MAX_ITEMS) {
      sem_wait(&empty);
      sem_wait(&mutex);

      buffer[in] = item;
      printf("Produced: %d</p><p>", item);
      item++;
      in = (in + 1) % BUFFER_SIZE;

      produced_count++;

      sem_post(&mutex);
      sem_post(&full);
   }

   pthread_exit(NULL);
}

void* consumer(void* arg) {
   while (consumed_count < MAX_ITEMS) {
      sem_wait(&full);
      sem_wait(&mutex);

      int item = buffer[out];
      printf("Consumed: %d</p><p>", item);
      out = (out + 1) % BUFFER_SIZE;

      consumed_count++;

      sem_post(&mutex);
      sem_post(&empty);
   }

   pthread_exit(NULL);
}

int main() {
   pthread_t producerThread, consumerThread;

   sem_init(&mutex, 0, 1);
   sem_init(&full, 0, 0);
   sem_init(&empty, 0, BUFFER_SIZE);

   pthread_create(&producerThread, NULL, producer, NULL);
   pthread_create(&consumerThread, NULL, consumer, NULL);

   pthread_join(producerThread, NULL);
   pthread_join(consumerThread, NULL);

   sem_destroy(&mutex);
   sem_destroy(&full);
   sem_destroy(&empty);

   return 0;
}

Dans cet exemple, une solution tampon limitée au problème producteur-consommateur est implémentée à l'aide de sémaphores. Les sémaphores sont utilisés pour contrôler l'accès aux tampons et synchroniser les threads producteurs et consommateurs. Les sémaphores mutex garantissent un accès mutuellement exclusif, les sémaphores complets suivent le nombre d'éléments dans le tampon et les sémaphores vides suivent le nombre d'emplacements vides disponibles. Ajout de conditions de résiliation pour limiter le nombre d'articles produits et consommés.

输出

Produced: 1
Consumed: 1
Produced: 2
Consumed: 2
Produced: 3
Consumed: 3
Produced: 4
Consumed: 4
Produced: 5
Consumed: 5

结论

生产者-消费者问题是并发编程中的一个重要挑战。通过理解问题并采用适当的同步技术,如互斥锁、条件变量、信号量或监视器,在C编程语言中可以开发出健壮的解决方案。这些解决方案使生产者和消费者能够和谐地共同工作,在并发系统中确保高效的数据生成和消费。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer