Здравствуйте, Sinclair, Вы писали:
V>>Нет такого понятия "совместимость блокировок" в матаппатаре блокировок (ограничений доступа к ресурсам) — это уже артефакт уровней изоляции, к собсно блокировкам не относится.
S>Да ладно!
Ну да.
А ты вообще хорошо себя чувствуешь — почитал какое-то руководство для пользователей к какой-то СУБД и с этими "знаниями" наперевес побежал спорить.
Попутал с форумом домохозяек? ))
S>А как тогда описываются в матаппарате блокировок отличия между shared и exclusive lock
Нет таких отличий.
В базе есть механизм семафора, у того счётчик.
Остальные примитивы сигнализации производные.
S>RO и RW блокировки в вашей терминологии.
Отношение RO и RW блокировок примерно равны отношению блокировок строк и страницы целиком, где эти строки располагаются.
(разве что у каждой строки есть своя блокировка, зависит от уровня изоляции).
Заявки, блокирующие строки, эквиваленты читателям, а блокирующие всю страницу — писателям.
Изначально значение семафора ресурса "достаточно большое" (не имеет смысла ставить выше уровня конкурентности многопроцессорной системы).
При появлении писателя семафору ресурса присвается значение счётчика "минус кол-во читателей плюс один".
Когда последний читатель освободит ресурс, писатель сможет его захватить.
Одно но — на многопроцессорной машине в режиме вытесняющей многозадачности наших "очередей" нет, есть очереди уровня ОС, поэтому возможно голодание писателей, т.к. даже при ограничении доступа к ресурсу счётчиком 1, его могут захватить конкурентные потоки-читатели.
Проблема голодания писателей решается либо системой управляемых приложением очередей, либо доп.механизмом на семафоре со счётчиком 1 — на т.н. турникете.
Т.е., система прикладных очередей предпочтительней в случае сложных иерархических блокировок, реализуется, например, через асинхронщину или "зеленые потоки", когда мы сами управляем нагрузкой, бо лишние примитивы сигнализации всегда дороги, да еще потенциально вносят помехи в системах с вытесняющей многозадачностью — например, поток читателя должен пройти через турникет, т.е. дёрнуть примитив сигнализации дважды, но поток может быть вытеснен после первой фазы прохода через турникет и тогда этот поток затормозит всех — и читателей и писателей.
В общем, при организации сложных иерархий доступа к ресурсам рулит кооперативная многозадачность.
В этом смысле планировщики ОС тупые. ))
Не потому что алгоритмы планировщика тупые, а потому что эти алгоритмы не обладают информацией о происходящем на прикладном уровне.
В системе с явными очередями читатели поступают из многих очередей (столько очередей, какова конкурентность системы), а писатели поступают из одной.
При появлении первого писателя все вновь поступающие читатели ставятся в очередь писателей (либо эти очереди просто "перекрываются").
При появлении из той очереди первого читателя они опять раскидываются по очередям читателей до появления первого писателя (либо очереди читателей опять открываются) и т.д.по кругу.
Простой и элегантный алгоритм, рекомендую.
Этим же алгоритмом точно так же элегантно обслужишь отношение блокировок уровня строки и страницы.
S>Давайте уберём "уровни изоляции", оставив только serializable.
S>Я правильно понимаю, что после этого нам не потребуется различать shared и exclusive блокировки?
Ты задаёшь новые вопросы не дожидаясь ответа на старые.
Я думаю, что ты и сам довольно просто сможешь ответить на такие вопросы, расписав происходящее (любой сценарий) на "ресурсах", очередях к ним и охраняющих ресурсы семафорах с разным значением счётчика.
Если значение счётчика семафора более 1, то ресурс могут "шарить" более одной заявки.
А вообще, насколько принципиально отличаются семафоры со счётчиком=1 от семафора со счётчиком=x?
ИМХО, отличие там на прикладном уровне.
Иногда может иметь значение отличие 2 от 3. ))
Есть еще сам прекрасный механизм очередей — очередь выдаёт новую заявку после того, как прежняя освободит ресурс(ы).
И да, небольшой хинт — при попытках расписывать происходящее на семафорах не имеет смысла думать семафорами уровня ОС, где очереди к семафорам "даны сверху", а сами ОС реализуют выталкивающую многозадачность.
Представь, что у тебя есть просто модель счётчика, управлять которым ты можешь атомарно.
Если не охота возиться с зелеными потоками, то в моделирующей программе это можно сделать, например, через цикл CAS:
while(!CAS(&sema_counter, new_value, old_Value)) {
asm ("pause");
old_value = sema_counter;
new_Value = calc_new_value(oldValue);
}