Синхронизация доступа к двусвязный список

Я пытаюсь реализовать (особый вид) двусвязный список на C в среде pthreads, но с использованием только команд синхронизации с оболочкой C, таких как атомарный CAS и т. Д., А не примитивов pthread. (Элементы списка представляют собой фрагменты памяти фиксированного размера и почти наверняка не могут поместиться в них pthread_mutex_t и т. Д.) На самом деле мне не нужны полные методы произвольного двусвязного списка, только:

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

Так что, возможно, лучшим способом описания этой структуры данных была бы очередь / FIFO с возможностью удаления элементов из середины очереди.

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

Правка : В частности, я застрял в том, что делать, если соседние объекты должны быть удалены одновременно. Предположительно при удалении объекта, вам необходимо получить блокировки как для предыдущего, так и для следующего объектов в списке и обновить их указатели next / prev, чтобы они указывали друг на друга. Но если любой из соседей уже заблокирован, это приведет к тупиковой ситуации. Я попытался разработать способ, которым любое / все происходящие удаления могли пройти заблокированную часть списка и определить максимальный подсписок, который в настоящее время находится в процессе удаления, а затем заблокировать узлы, смежные с этим подсписком, чтобы весь подсписок удаляется целиком, но у меня начинает болеть голова .. :-P

Заключение (?) : В продолжение, у меня есть код, который я хочу запустить, но я тоже интересует теоретическая проблема. Все ответы были весьма полезны и в сочетании с деталями ограничений, выходящих за рамки того, что я здесь выразил (вы действительно не понимаете) Я не хочу знать, откуда взялся указатель на удаляемый элемент и какая синхронизация там задействована!) Я решил пока отказаться от кода локальной блокировки и сосредоточиться на:

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

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

6
задан R.. 3 December 2010 в 11:29
поделиться