Я написал многопоточную программу «производитель-потребитель» на C. Моя первоначальная программа не была Minimal / Complete / Verifiable, поэтому я переписал ее с нуля, и ошибка все еще происходит.Я обнаружил, что несколько потоков производителей пытаются создать одни и те же данные (из последовательности данных), и я не уверен, как это остановить.
Некоторые вещи, которые я пробовал: - Я создалмассив bool того же размера, что и буфер, чтобы убедиться, что потоки только помещают данные в пустой слот, и берут из одного с данными в нем, это решило одну проблему - я попытался переместить приращение слота ввода / вывода в началоцикл «производитель / потребитель» выполняет циклы (соответственно), но это вызывает тупик
Еще одна не связанная с этим проблема (я вполне могу решить себя завтра, но на данный момент все так, как есть) состоит в том, что многие значения в последовательностипропущены, хотя я хочу, чтобы они все были произведены.
ОБРАТИТЕ ВНИМАНИЕ: я изучаю C в течение одного месяца, и это также мой первый пост здесь.Я многому научился на этом сайте за последние несколько лет, и я знаю, что иногда ответы здесь могут быть довольно резкими, поэтому, пожалуйста, будьте добры к тому, кто искренне хочет учиться и совершенствоваться.Спасибо!:)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
char * Buffer;
int nBufferSlots = 10;
int nThreads = 2;
pthread_t Producers, Consumers;
sem_t Empty, Full, Mutex;
int inputSlot;
int outputSlot;
char value = 0;
char SlotOccupationBoolArray[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
void * producer(void *args)
{
while(1)
{
sleep( rand() % 3);
value++;
sem_wait(&Empty);
sem_wait(&Mutex);
if (SlotOccupationBoolArray[inputSlot] == 0)
{
Buffer[inputSlot] = value;
SlotOccupationBoolArray[inputSlot] = 1;
}
else
{
value--;
}
inputSlot = (inputSlot + 1) % nBufferSlots;
sem_post(&Mutex);
sem_post(&Full);
printf("\n[ ");
for (int i=0;i<10;i++)
{
printf("%d ", Buffer[i]);
}
printf("]\n");
}
}
void * consumer(void *args)
{
while(1)
{
sleep( rand() % 5);
sem_wait(&Full);
sem_wait(&Mutex);
if (SlotOccupationBoolArray[outputSlot] == 1)
{
char ValueConsumed = Buffer[outputSlot];
printf("\nConsumed value: %d\n", ValueConsumed);
Buffer[outputSlot] = 0;
SlotOccupationBoolArray[outputSlot] = 0;
}
outputSlot = (outputSlot + 1) % nBufferSlots;
sem_post(&Mutex);
sem_post(&Empty);
}
}
int main(void)
{
sem_open("/Mutex", O_CREAT, S_IRUSR | S_IWUSR, 1);
sem_open("/Full", O_CREAT, S_IRUSR | S_IWUSR, 0);
Buffer = (char*) malloc(nBufferSlots*sizeof(char));
sem_open("/Empty", O_CREAT, S_IRUSR | S_IWUSR, nBufferSlots);
Producers = (pthread_t) malloc(nThreads*sizeof(pthread_t));
Consumers = (pthread_t) malloc(nThreads*sizeof(pthread_t));
// set charBuffer elements to 0
for (char i=0;i<10;i++)
{
Buffer[i] = 0;
}
for (int i = 0; i < nThreads; i++)
{
pthread_create(&Producers, NULL, producer, NULL);
pthread_create(&Consumers, NULL, consumer, NULL);
}
for(int i=0;i<nThreads;i++){
int err = pthread_create(&Producers,NULL,producer,NULL);
if(err != 0){
printf("Error creating producer %d\n",i+1);
}else{
printf("Successfully created producer %d\n",i+1);
}
}
for(int i=0;i<nThreads;i++){
int err = pthread_create(&Consumers,NULL,consumer,NULL);
if(err != 0){
printf("Error creating consumer %d\n",i+1);
}else{
printf("Successfully created consumer %d\n",i+1);
}
}
pthread_exit(NULL);
}
Все, что мне нужно вывести на печать - это массив буферов с текущими значениями (каждый раз, когда запускается поток производителя) и каждым использованным значением.
Что бы я хотелхотелось бы видеть в выводе что-то вроде этого:
- [1 0 0 0 0 0 0 0 0 0]
- [1 2 0 0 0 0 0 0 0 0]
- [1 2 3 0 0 0 0 0 0 0]
- Потребляемая стоимость: 1
- [0 2 3 4 0 0 0 0 0 0]
- [0 2 3 4 5 0 0 0 0 0]
- Потребляемая стоимость: 3
- [0 2 0 4 5 0 0 0 0 0]
- Потребляемая стоимость: 4
- [0 2 0 0 5 6 0 0 0 0]
- [0 2 0 0 5 6 7 0 0 0]
Но вместо этогоЯ вижу что-то вроде этого (дубликат 2/4 - это проблема):
- [2 2 4 4 5 6 0 0 0 0]
- [2 2 4 4 56 7 0 0 0]
- [2 2 4 4 5 6 7 8 0 0]
- Потребляемая стоимость: 2
- Потребляемая стоимость: 2
- [0 0 4 4 5 6 7 8 9 0]
- Потребляемая стоимость: 4
(Извинения заформатирование)