경계 버퍼로 생산자 문제를 해결하기 위해 세마포어를 사용하여 C에서 모니터를 구현하려고했습니다. 다음은 모니터를 구현하는 데 사용한 코드입니다.세마포어를 사용하여 C에서 모니터를 구현하면 교착 상태가 발생합니다.
#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);
}
}
는 이것은 내 주요 파일 (주요 기능)입니다 :
#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;
}
하지만 불행히도 그것은 교착 상태에 이르게. 나는 프로세스를 점검하고 모든 생산자와 소비자가 뮤텍스를 기다리는 것을 발견했다. 어떻게해야합니까?
'producerCount' 또는'consumerCount '가 0이 아닌 것은 확실합니까? 디버거로 코드를 밟았습니까? – jwdonahue
나는 10 명의 생산자와 10 명의 소비자를 생성하고, 프로그램의 어느 시점에서 이들 모두가 차단되었다고 확신하며, 그들은 세마포어 뮤텍스를 공개하기를 기다리고있다. – zari
값으로 세마포를 통과 할 수 있습니까? –