Как предотвратить голодание писателя при блокировке чтения и записи в pthreads - PullRequest
28 голосов
/ 03 февраля 2010

У меня есть несколько вопросов, касающихся блокировок чтения-записи в Pthread-файлах POSIX в системе * nix, например, в Linux.

Я хочу знать, каково смещение по умолчанию для блокировки чтения-записи, то есть предпочитает ли оно чтениепереписывает или наоборот?Предоставляет ли он некоторые API для изменения этого поведения по умолчанию.

Предоставляет ли Posix pthread некоторые API, чтобы мы могли изменить pthread_rwlock_t, чтобы предотвратить голодание писателя?Из того, что я прочитал (пожалуйста, исправьте меня, если я ошибаюсь), реализация по умолчанию смещена в сторону потоков читателя, и поэтому потоки писателя могут столкнуться с голодом.

Я прочитал пример реализации блокировки rw из книги Программированиес потоками Posix Дэвида Бутенхофа.

Я хотел бы знать, как posix pthreads справляется с голодом писательских потоков?Есть ли какой-нибудь API, с помощью которого мы могли бы установить атрибуты блокировки чтения-записи, которые предотвратили бы голодание при записи (я никогда об этом не слышал)?Или пользователь должен решить эту проблему?

Если вы считаете, что ответ зависит от реализации, пожалуйста, приведите пример того, как это делается в Linux, потому что это то, что я ищу.

Обратите внимание, что я просто хочу решения для системы * nix.Не думайте, что я груб, но публикация кода для Windows бесполезна для меня.

Спасибо всем за помощь и терпение :)

1 Ответ

42 голосов
/ 03 февраля 2010

Это действительно зависит от реализации - поэтому, поскольку вы спрашивали конкретно о Linux, мои комментарии относятся к текущей реализации pthreads в NPTL, которая используется в современном glibc.

Здесь есть две связанные, но отдельные проблемы. Во-первых, есть такая ситуация:

  • В настоящее время существуют блокировки чтения, и авторы ждут. Новый поток пытается получить блокировку чтения.

Действие по умолчанию здесь - позволить читателю продолжить работу - эффективно «перепрыгивая очередь» через писателя. Вы можете, однако, переопределить это. Если вы используете функцию pthread_rwlockattr_setkind_np() для установки флага PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP на attr, который вы передаете на pthread_rwlock_init(), тогда ваш rwlock заблокирует считыватель в вышеуказанной ситуации.

Вторая ситуация:

  • Последний владелец снимает блокировку, и там ждут как читатели, так и писатели.

В этой ситуации NPTL всегда будит писателя в предпочтении читателя.

В совокупности вышеприведенное означает, что если вы используете флаг PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, ваши писатели не должны голодать (конечно, теперь непрерывный поток писателей может голодать читателей. C'est la vie ). Вы можете подтвердить все это, проверив источники (все они очень читабельны 1 ) в pthread_rwlock_rdlock.c и pthread_rwlock_unlock.c .

Обратите внимание, что есть также PTHREAD_RWLOCK_PREFER_WRITER_NP, но, похоже, не имеет правильный эффект - вполне возможно, ошибка ( или, возможно, нет - см. комментарий от jilles ниже ** 1040).


1. ... или, по крайней мере, так было, когда я писал этот ответ в 2010 году. Последние версии NPTL значительно сложнее, и я не проводил повторный анализ.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...