Ich habe versucht, Monitor in C mit Semaphor zu implementieren, um Producer Consumer Problem mit begrenzten Puffer zu lösen. Folgendes ist der Code, mit dem ich Monitor implementiert habe.Implementieren von Monitor in C mit Semaphor, führt zu Deadlock
#include<semaphore.h>
int availableItemCounts;
int bufferSize;
int itemShouldBeProducedCount;
int itemShouldBeConsumedCount;
int availableItemIndex;//index of last item inserted in buffer.
char *buffer;
sem_t mutex;
typedef struct
{
sem_t semaphore;
int numberOfBlockedThreads;
} Condition;
Condition bufferIsFull, bufferIsEmpty;
int countCV(Condition conditionVariable)
{
return conditionVariable.numberOfBlockedThreads;
}
void waitCV(Condition conditionVariable)
{
conditionVariable.numberOfBlockedThreads++;
sem_wait(&(conditionVariable.semaphore));
}
void signalCV(Condition conditionVariable)
{
if(countCV(conditionVariable)>0)
{
sem_post(&(conditionVariable.semaphore));
conditionVariable.numberOfBlockedThreads--;
}
else
{
sem_post(&mutex);
}
}
void monitorInit(int buffSize, int itemSBPC,int itemSBCC)
{
availableItemCounts=0;
availableItemIndex=-1;
bufferSize=buffSize;
itemShouldBeProducedCount=itemSBPC;
itemShouldBeConsumedCount=itemSBCC;
char tempBuffer[bufferSize];
buffer=tempBuffer;
sem_init(&(bufferIsFull.semaphore), 0, 0);
sem_init(&(bufferIsEmpty.semaphore), 0, 0);
sem_init(&(mutex), 0, 1);
bufferIsEmpty.numberOfBlockedThreads=0;
bufferIsFull.numberOfBlockedThreads=0;
}
void monitor_Insert(char item)
{
sem_wait(&mutex);
if (itemShouldBeProducedCount>0)
{
if(availableItemCounts==bufferSize)
{
sem_post(&mutex);
waitCV(bufferIsFull);
sem_wait(&mutex);
}
availableItemIndex++;
buffer[availableItemIndex]=item;
printf("p:%lu, item: %c, at %d\n", pthread_self(), item, availableItemIndex);
itemShouldBeProducedCount--;
availableItemCounts++;
signalCV(bufferIsEmpty);
}
else
{
sem_post(&mutex);
pthread_exit(NULL);
}
}
void monitor_Remove(char item)
{
sem_wait(&mutex);
if (itemShouldBeConsumedCount>0)
{
if(availableItemCounts==0)
{
sem_post(&mutex);
waitCV(bufferIsEmpty);
sem_wait(&mutex);
}
item=buffer[availableItemIndex];
printf("c:%lu, item: %c, at %d\n", pthread_self(), item, availableItemIndex);
availableItemIndex--;
itemShouldBeConsumedCount--;
availableItemCounts--;
signalCV(bufferIsFull);
}
else
{
sem_post(&mutex);
pthread_exit(NULL);
}
}
und das ist meine Hauptdatei (Hauptfunktion):
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<stdlib.h>
#include "Monitor.h"
void *produce(void *index);
void *consume(void *index);
int itemShouldBeProducedCount;//total number of items that should be produced.
int itemShouldBeConsumedCount;//total number of items that should be consumed.
int bufferSize;
int main(int argc, char **argv)
{
int index;
int error;
int producerCount=atoi(argv[4]);
int consumerCount=atoi(argv[6]);
itemShouldBeProducedCount=atoi(argv[8]);
itemShouldBeConsumedCount=itemShouldBeProducedCount;
bufferSize=atoi(argv[2]);
monitorInit(bufferSize,itemShouldBeProducedCount,itemShouldBeConsumedCount);
sem_init(&(bufferIsFull.semaphore), 0, 0);
sem_init(&(bufferIsEmpty.semaphore), 0, 0);
printf("Producer Count:%d\n", producerCount);
printf("Consumer Count:%d\n", consumerCount);
printf("Buffer size Count:%d\n", bufferSize);
printf("Items should be produced:%d\n", itemShouldBeProducedCount);
printf("Items should be consumed:%d\n", itemShouldBeConsumedCount);
monitorInit(bufferSize,itemShouldBeProducedCount,itemShouldBeConsumedCount);
pthread_t producerThreads[ producerCount ];
pthread_t consumerThreads[ consumerCount ];
for(index = 0; index < producerCount; index++)
{
printf("In main: creating producer thread %d\n", index);
error = pthread_create(&producerThreads[index], NULL, produce, &index);
}
for(index = 0; index < consumerCount; index++)
{
printf("In main: creating consumer thread %d\n", index);
error = pthread_create(&consumerThreads[index], NULL, consume, &index);
}
// wait for each producer thread to complete
for(index = 0; index < producerCount; ++index)
{
// block until thread 'index' completes
pthread_join(producerThreads[ index ], NULL);
printf("In main: producer thread %d has completed\n", index);
}
// wait for each consumer thread to complete
for(index = 0; index < consumerCount; ++index)
{
// block until thread 'index' completes
pthread_join(consumerThreads[ index ], NULL);
printf("In main: consumer thread %d has completed\n", index);
}
sem_destroy(&(bufferIsFull.semaphore));
sem_destroy(&(bufferIsEmpty.semaphore));
return 0;
}
void *produce(void *threaID)
{
unsigned char item;
while(1)
{
item= (unsigned char) (rand() % 256);//generating an item
monitor_Insert(item);
}
return NULL;
}
void *consume(void *threaID)
{
while(1)
{
char item;
monitor_Remove(item);
}
return NULL;
}
aber leider führt es in einer Sackgasse. Ich habe die Prozesse überprüft und festgestellt, dass alle Produzenten und Konsumenten auf Mutex warten. Was soll ich machen?
Sind Sie sicher, dass weder 'producerCount' noch' consumerCount 'gleich null sind? Sind Sie mit einem Debugger in den Code gegangen? – jwdonahue
Ich bin sicher, dass es 10 Produzenten und 10 Konsumenten erzeugt, und alle von ihnen an irgendeinem Punkt im Programm werden blockiert, während sie darauf warten, Semaphore Mutex freizugeben. – zari
Können Sie jemals einen Semaphor nach Wert übergeben? –