This will reduce how often the pipe is full, but not eliminate it.
Paradigm change: adjust the reader to throw away a percentage of reads.
Writer
When the writer sees a full queue, then next number it writes is a special number (e. g. NaN), and thens it writes the desired number.
Reader
The reader is set to throw away P percent of numbers.
The reader reads a number - waiting as needed. If it is not a candidate to throw away, proceed as usual.
When the reader considers throwing away a number to meet its throw-away percentage, it 1st tests if the pipe is empty. If so, the reader knows to reduce the percentage being thrown away and uses the number first read. If the pipe is not empty, it reads the pipe, throwing away the first number and using the 2nd.
When the reader reads the special number, it knows it is not throwing away enough numbers and increases its percentage, then it reads the pipe again.
If the overall performance of the reader and writer side does not vary too much, the reader will be throwing away 1 number every so often balancing the swift writer and the plodding reader performance. If there is a slight skewing favoring an empty queue over a full one, the pipe will rarely fill and the reader will more often receive fresh numbers.