На уроке по разработке ОС в колледже у меня был адъюнкт-учитель, который утверждал, что невозможно иметь программное решение, которое могло бы использовать все 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;
consIdx = (consIdx + 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.
}
}
}
Прошло много времени с тех пор, как я изначально решил проблему, поэтомупо моим лучшим воспоминаниям.Надеюсь, я не пропустил никаких ошибок.Надеюсь, это поможет!