Трудно оценить проблему, не имея более подробной информации, но вот мой выстрел в темноте: я подозреваю, что в вашем сценарии читатели должны очень часто приобретать блокировки (в противном случае вам, вероятно, будет лучше с традиционной блокировкой),Вот ваша проблема:
Любой отдельный поток может лишить всех других ресурсов.
Это верно как для читателей, так и для писателей, хотя в несправедливом алгоритме этообычно верно только для писателей.Проблема в вашей ситуации возникает, когда у вас есть несколько читателей, стоящих в очереди для доступа для чтения.Каждый поток будет ждать, пока предыдущая блокировка станет доступной (while (lock_pool[prev_reader_id].is_locked) ...
).Если они могут получить эту блокировку, все в порядке, но вы попадете в беду, как только один поток не сможет ее получить.Все потоки читателей стоят в очереди, чтобы увидеть, как их предшественники переключаются на false
.Каждый из них зависит от своего прямого предшественника.
Теперь представьте, что первый читатель не может получить блокировку.Это будет вращаться некоторое время и в конечном итоге yield()
.Это фактически означает, что ваш поток больше не работает.Операционная система удалила его из очереди планирования, и он не будет работать в течение long времени (остальная часть их временного интервала, что является длинным по сравнению с тем, сколько времени требуется для завершения 100 вращений).Как следствие, полная цепочка ожидающих потоков с большой вероятностью перейдет в yield.
В конце концов флаг, ожидающий первого потока, переключится на false
.Но ваш планировщик сейчас в затруднительном положении.Вокруг него куча нитей, но они вращаются только очень короткое время, прежде чем снова начинают приносить доход.Здесь ожидается, что для всех, кроме первой нити в цепочке, если они будут выбраны, они почти наверняка будут обречены на бездействие для еще одного полного временного интервала.Как следствие, если это случается с потоком в начале цепочки ожидающих потоков, вы также осуждаете все другие потоки в цепочке ждать как минимум столько же времени.
То, что вы играете здесь, это игравероятность того, что ваши шансы на победу значительно уменьшатся с ростом числа читателей в очереди.Вот почему проблема усугубляется при переходе от 4 до 16 потоков.В частности, как только вы достигнете точки, когда среднее время, необходимое для того, чтобы новый читатель прибыл в очередь, примерно соответствует времени, которое требуется потоку, чтобы пройти через очередь, вам будет трудно вернуться назад.в пустую очередь снова.Это не исключено, так как мы говорим здесь несколько временных интервалов, что приводит вас к порядку от десятков до сотен миллисекунд.
Это типичный компромисс в алгоритмах честного планирования.Справедливость достигается ценой, в этом случае один читатель может заблокировать каждого.Поскольку мой читатель никогда не сможет обогнать вашего читателя, если вам сначала удастся дозвониться до звонка, мне придется ждать вечно, если вы не будете двигаться дальше.Одним из решений этой проблемы является предоставление планировщику дополнительной информации о том, что ожидает каждый поток, так что у него больше шансов разбудить их в правильном порядке.Другой - выбрать другой алгоритм, который лучше подходит для вашего конкретного сценария.