На уроке по разработке ОС в колледже у меня был адъюнкт-учитель, который утверждал, что невозможно иметь программное решение, которое могло бы использовать все N элементов в буфере.
Я доказал, что он не прав с чем-то, что я решил назвать решением для гоночной трассы (вдохновленный тем, что мне нравится бегать по трассе).
На гоночной трассе вы не ограничены 400-метровой гонкой; гонка может состоять из более чем одного круга. Что случится, если два бегуна будут шеей и шеей
в гонке? Как вы знаете, связаны ли они, или один бегун плеснул другого? Ответ прост: в гонке мы не контролируем позицию бегуна
на трассе; мы отслеживаем расстояние, пройденное каждым бегуном. Таким образом, когда два бегуна являются шеей и шеей, мы можем различить между галстуком и когда один бегун имеет
плескался другой.
Итак, наш алгоритм имеет массив из N элементов и управляет гонкой 2N. Мы не перезагружаем счетчик производителя / потребителя до нуля, пока они не закончат свою соответствующую гонку 2N.
Мы не позволяем производителю опережать потребителя более чем на один круг, и мы не позволяем потребителю опережать производителя.
На самом деле, нам нужно только отслеживать расстояние между производителем и потребителем.
Код выглядит следующим образом:
Item track[LAP];
int consIdx = 0;
int prodIdx = 0;
void consumer()
{ while(true)
{ int diff = abs(prodIdx - consIdx);
if(0 < diff) //If the consumer isn't tied
{ track[consIdx%LAP] = null;
prodIdx = (prodIdx + 1) % (2*LAP);
}
}
}
void producer()
{ while(true)
{ int diff = (prodIdx - consIdx);
if(diff < LAP) //If prod hasn't lapped cons
{ track[prodIdx%LAP] = Item(); //Advance on the 1-lap track.
prodIdx = (prodIdx + 1) % (2*LAP);//Advance in the 2-lap race.
}
}
}
Прошло много времени с тех пор, как я изначально решил проблему, так что, насколько я помню. Надеюсь, я не пропустил никаких ошибок.
Надеюсь, это поможет!