2008-10-06 5 views

ответ

-1

Мой первый импульс (я не эксперт):

иметь блокировку этого объекта, что код использует для записи в него. Когда вы глубоко копируете, блокируете объект, выполняете свою глубокую копию и затем разблокируете.

Или я чего-то не хватает?

+1

Не так просто, как кажется, учитывая, что здесь используется глубокая копия. В графе объектов есть потенциально много блокировок для разных частей данных. Очень, очень легко либо пропустить один, либо зайти в тупик. – Andrew 2008-10-06 23:57:18

4

В зависимости от ваших структур данных.

Я предполагаю, что проблема, с которой вы сталкиваетесь (хотя вы этого не говорите), является потенциальной инверсией блокировки. Если вы глубоко копируете, вы, вероятно, возьмете одну или несколько замков для различных объектов, которые вам нужно скопировать.

Если вы можете определить DAG (то есть частичный порядок), где узлы являются каждой блокировкой в ​​системе, и каждая комбинация блокировок, которые вы могли бы захотеть предпринять, связана с краями, тогда вы можете обеспечить блокировку никогда не принимаются в разных порядках в разных потоках. Следовательно, в частности, вы не получите блокировки инверсии. Типичным правилом является принятие последнего «наиболее общего» блокирования, поскольку это приводит к минимизации конкуренции.

Но если вы глубоко копируете один из целых кучей «WidgetBoxes», каждый из которых содержит «Виджеты», которые в основном неразличимы, с возможным перекрытием между содержимым ящиков, тогда у вас есть проблема, определяющая порядок блокировки естественным образом. Кроме того, вам придется сначала заблокировать WidgetBox (даже если это «самый общий» объект), так как без этой блокировки вы не можете сказать, что еще нужно блокировать. Если Виджеты сопоставимы, вы можете заблокировать их по порядку, сделать свою копию и освободить все. Насти.

Альтернативой является определение единой блокировки, общей для всех виджетов и виджетов. Это может привести к большим разногласиям, и в этом случае оптимистическая блокировка может улучшить ситуацию, при условии, что одновременно с копиями произойдет не слишком много изменений.

Другой альтернативой может быть ослабление гарантий, которые вы делаете о копии, вместо того, чтобы требовать, чтобы полная копия была сделана из идентифицируемого состояния глубокой структуры, вы можете сначала заблокировать WidgetBox, неглубоко скопировать ее (используя пересчет или независимо от того, что блокировка при пересчете, как правило, является «конечной внутренней блокировкой» и, следовательно, не является риском инверсии), отпустите блокировку WidgetBox, а затем скопируйте каждый из виджетах поочередно. Используйте тот же подход к копированию виджетов, если они имеют внутреннюю структуру. Результат может содержать виджет в состоянии, которого он не достиг, пока он не будет удален из WidgetBox в другом потоке или других подобных несоответствиях, поэтому, если это неприемлемо, вы не сможете использовать этот подход. Но если вы только блокируете один объект за раз в каждом потоке, вы не можете получить блокировку инверсии.

Последний, возможный «ядерный» вариант - сделать все неизменным и всегда копировать при модификации. Если ничто не может быть изменено, тогда вам не нужны блокировки (хотя вам все равно нужны барьеры памяти при передаче ссылок между потоками).

Если ни одна из этих работ не работает, то вы не в моем опыте, если я ничего не забыл. Я бы предположил, что реализация базы данных где-то, что много связанных с блокировкой умение продолжается, и это будет область, чтобы обратиться за идеями.

0

fork()

Я просто шучу.Но было слишком смешно переходить :)

Я думаю, что onebyone покрыл большинство ваших вариантов. Кроме того, возможно, отступив назад и посмотрим, сможете ли вы найти способ избежать глубокой копии в первую очередь ...

Смежные вопросы