В основном я ищу библиотеку графика, которая имела бы мелкомодульную блокировку вокруг операций графика, так, чтобы различные потоки, касающиеся различных частей графика, могли изменить ее одновременно, и могли быть заблокированы конкурирующие модификации.
Я погуглил вокруг немного и ничего не могу найти. Возможно, это слишком характерно для моих потребностей, но я предположил бы, что там будет существовать большое количество научных приложений, которые работали бы над большими графиками.
Возможно, вы захотите взглянуть на Библиотеку параллельных графиков ускорения (и, возможно, на Многопоточный график Библиотека ). Я сам еще не использовал ни то, ни другое, просто наткнулся на них, рассматривая параллелизм как вариант ускорения некоторого кода BGL . теперь официально в усилении !хороший обзор архитектуры , но, возможно, их понятие «распределенного графа» является довольно грубым по сравнению с тем, что вы имели в виду).
Предположим, вы спрашиваете о графиках как о математической сущности (например, о типах графиков, обрабатываемых GraphBase ) - тогда я не думаю, что вы найдете то, что вы ищете, по крайней мере, в библиотеке общего назначения.
Проблема в том, что «потокобезопасность» на самом деле не является четко определенным термином во всех контекстах - как минимум, это, вероятно, означает, что ваша программа, вероятно, не будет взорваться перед лицом параллельной обработки из нескольких потоков - но помимо этого требования, даже что-то вроде контейнера или алгоритма, который претендует на то, чтобы быть «безопасным для протектора», будет иметь некоторую дополнительную семантику относительно того, что именно это означает - и граф общего назначения библиотека еще более сложна, и для этого потребуется еще более точная (и настраиваемая) семантика.
Например (говоря о простом объекте - скажем, о контейнере):
Разрешен ли одновременный доступ для чтения к одному и тому же объекту? Разрешен ли одновременный доступ на запись к одному и тому же объекту? Читатели блокируют читателей? Читатели блокируют писателей? Блокируют ли писатели писателей? В более общем плане, какие операции блокируют другие операции?
Хотя вы можете определить разумную семантику для простых контейнеров - например, для параллельного набора - даже после того, как вы перейдете к чему-то вроде карты, вам нужно ввести составные операции, такие как «putIfAbsent», чтобы компенсировать тот факт, что многим приложениям требуется нечто большее, чем безопасность потоков - им необходимо связать вместе операции, которые обычно выполнялись в отдельных вызовах (поиск, затем добавление), в логически атомарную операцию.
Я подозреваю, что с чем-то вроде библиотеки графов, эта проблема становится острой. Ваше приложение должно будет определить, какие операции могут выполняться параллельно - какие операции должны блокировать другие, нужно ли вам иметь возможность делать согласованный снимок графа, нужна ли вам полная сериализуемость операций на графе, для большинства экземпляров данного класса) - с предположением, что потокобезопасность может быть добавлена извне теми, кому это необходимо, но что обратное преобразование (удаление потоковой безопасности) обычно невозможно. Java пошла по этому пути, эффективно отказавшись от некоторых из ранних поточно-ориентированных классов, таких как Vector, в пользу ArrayList и StringBuffer против StringBuilder.
С другой стороны, предположение, что клиенты могут добавить потокобезопасность к внешние контейнеры (без доступа к внутренним компонентам) часто являются некорректными, что лежит в основе потоковобезопасных контейнеров, созданных из группы в параллельном пакете. Однако я очень сомневаюсь, что вы найдете эквивалент для манипуляции с графами в C ++.
Обновление: В свете других ответов, я думаю, я должен подчеркнуть, что я не думаю, что вы »
К сожалению, стоимость мелкозернистой блокировки, скорее всего, выше, чем ускорение из нескольких потоков. Не говоря уже о риске дедлока, управление блокировкой становится более сложным, когда у вас больше, чем очень небольшое количество мьютексов.
.