множественное чтение и единичная запись через мьютексы, shared_mutex, shared_lock, upgrade_lock |
Здравствуйте, гость ( Вход | Регистрация )
множественное чтение и единичная запись через мьютексы, shared_mutex, shared_lock, upgrade_lock |
Mifodix |
27.5.2011, 22:25
Сообщение
#1
|
Новичок Группа: Новичок Сообщений: 9 Регистрация: 7.6.2010 Пользователь №: 1789 Спасибо сказали: 0 раз(а) Репутация: 0 |
Всем доброго времени!
Чтобы проще описать мою проблему, рассмотрим следующую программу:
Необходимо как-то реализовать через мьютексы множественное чтение списка (т. е. все потоки, использующие thread_func_read могут одновременно читать) и единичную запись (т. е. только один поток в настоящее время может производить запись в список). При этом запись в список должна быть возможна только после завершения чтения этого списка другими потоками, а само чтение невозможно, если в список производится запись. Несколько потоков не могут писать одновременно. С первой часть всё понятно: нужно использовать shared_lock. А вот как быть с ограничением на запись? Заранее спасибо! |
|
|
Алексей1153 |
28.5.2011, 10:31
Сообщение
#2
|
фрилансер Группа: Участник Сообщений: 2939 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: 34 |
и чтение, и запись должны одинаково закрываться в "критическую секцию". При чтении нужно быстренько копировать элемент из списка во внешнюю (относительно секции) переменную, удалять, если это нужно, элемент из списка, затем покидать секцию.
Любые другие извращения до добра не доведут
Сообщение отредактировал Алексей1153 - 28.5.2011, 10:33 |
|
|
Iron Bug |
28.5.2011, 14:06
Сообщение
#3
|
Профессионал Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: 12 |
это так называемый UpgradeLockable Concept.
есть расшаренные мьютексы, которые могут быть "проапгрейджены" до монопольного владения. если никто не заявил право на монополию, то все пользуются ресурсом. если кто-то захватил монополию - никто не имеет доступ до освобождения монополии. подробно читать тут: http://live.boost.org/doc/libs/1_44_0/doc/...pgrade_lockable |
|
|
Mifodix |
28.5.2011, 19:33
Сообщение
#4
|
Новичок Группа: Новичок Сообщений: 9 Регистрация: 7.6.2010 Пользователь №: 1789 Спасибо сказали: 0 раз(а) Репутация: 0 |
это так называемый UpgradeLockable Concept. есть расшаренные мьютексы, которые могут быть "проапгрейджены" до монопольного владения. если никто не заявил право на монополию, то все пользуются ресурсом. если кто-то захватил монополию - никто не имеет доступ до освобождения монополии. подробно читать тут: http://live.boost.org/doc/libs/1_44_0/doc/...pgrade_lockable Большое спасибо за ссылку, однако я не смог самостоятельно разобраться Следующий код падает:
Не понимаю как апгрейдить блокировку на запись только с одного потока. |
|
|
Iron Bug |
28.5.2011, 21:27
Сообщение
#5
|
Профессионал Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: 12 |
у тебя поток на чтение захватывает лок сразу же после создания объекта read_lock и дополнительно лочить его не требуется: попытка повторного лока приведёт к экспешену. после создания объекта shared_lock можно только разлочивать его и потом, по необходимости, снова лочить и так далее.
не надо торопиться. внимательнее читай документацию и смотри описания postcondition в функциях темплейтов для разных видов локов. плюс в бусте много примеров к каждой библиотеке. |
|
|
Mifodix |
29.5.2011, 0:06
Сообщение
#6
|
Новичок Группа: Новичок Сообщений: 9 Регистрация: 7.6.2010 Пользователь №: 1789 Спасибо сказали: 0 раз(а) Репутация: 0 |
у тебя поток на чтение захватывает лок сразу же после создания объекта read_lock и дополнительно лочить его не требуется: попытка повторного лока приведёт к экспешену. после создания объекта shared_lock можно только разлочивать его и потом, по необходимости, снова лочить и так далее. не надо торопиться. внимательнее читай документацию и смотри описания postcondition в функциях темплейтов для разных видов локов. плюс в бусте много примеров к каждой библиотеке. Вот с примерами как раз дело плохо Более-менее разобрался:
Читающие потоки действительно читают одновременно, а пишущие потоки ждут пока завершится читающий поток и ждут завершения друг друга (т.е. одновременно не пишут). Но вот в чём бага: если сначала выполняется пишущий поток, то читающий поток почему-то не ждёт его завершения, а начинает читать одновременно. Где я ошибся? |
|
|
Iron Bug |
29.5.2011, 12:24
Сообщение
#7
|
Профессионал Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: 12 |
сам по себе апгрейд ещё не есть захват эксклюзивного права на пользование ресурсом, а только заявка на то, что когда-то потом поток будет иметь право на такой захват. чтобы получить эксклюзивное - нужно его залочить. (см. exclusive ownership в доках к бусту) Сообщение отредактировал Iron Bug - 29.5.2011, 12:25 |
|
|
Mifodix |
29.5.2011, 17:51
Сообщение
#8
|
Новичок Группа: Новичок Сообщений: 9 Регистрация: 7.6.2010 Пользователь №: 1789 Спасибо сказали: 0 раз(а) Репутация: 0 |
сам по себе апгрейд ещё не есть захват эксклюзивного права на пользование ресурсом, а только заявка на то, что когда-то потом поток будет иметь право на такой захват. чтобы получить эксклюзивное - нужно его залочить. (см. exclusive ownership в доках к бусту) Хех, главное я сначала сделал unlock_upgrade_and_lock() + unlock_and_lock_upgrade(), потом lock_upgrade()+unlock_upgrade(), но вот вместе их использовать не догадался Большое вам спасибо за помощь! Почитаю ещё доки и попробую использовать эту концепцию в реальном проекте |
|
|
Текстовая версия | Сейчас: 29.4.2024, 20:03 |