У меня есть ориентированный ациклический граф, пример которого может выглядеть так:
|
(1)
/ | \
/ | \
(3) (2) (4)
/ / | \ \
/ / | \ \
/ / | \ \
(6)(7) (5) (8)(9)
| | | | |
(10)(11) (12)(13)(14)
\ \ | / /
\ \ (15)_/ /
\ \ | /
\___(16)__/
|
|
- Выполнение каждого узла происходит вниз.
- Если узел имеет более одной исходящей ветви, создается копия графа, и выбранная ветвь выполняется в другом процессе.
- Если узел имеет более одной входящей ветви, копии графа направляются обратно в главный процесс, чтобы их можно было объединить, чтобы в основной копии были все изменения, внесенные в ветви (в отдельных процессах).
- Процессы долго выполняются и являются переходными, поэтому я не могу / не хочу направлять каждый узел обратно к мастеру после того, как он был выполнен - я хочу объединяться с мастером только тогда, когда большая часть работы ( филиал) был завершен удаленно.
Так, например, на узле (1)
есть три ветви, которые должны синхронизироваться на узле (16)
. Само по себе это относительно просто - пометить узел (16)
как synch
для узла (1)
и объединить от узла (1)
до (16)
вниз по ветви, синхронизируемой, когда выполнение достигает (16)
.
Однако узел (2)
имеет две ветви, которые также должны синхронизироваться в узле (16)
(у него также есть две ветви, которые должны синхронизироваться в узле (15)
).
В этом примере проблема заключается в том, что когда выполнение достигает узла (16)
, он не знает, с какой глубины выполняется резервное копирование дерева для начала синхронизации (т. Е. Узла (1)
или (2)
).
Мне нужно что-то вроде схемы раскраски графа, в которой разные пути выполнения предоставляют свои собственные указатели на узел, из которого они произошли, поэтому, когда активирован путь (11) -> (16)
, выполнение знает, что часть графа должна быть объединена начинается в узле (2)
.
Есть ли какая-то теория или алгоритм, который может здесь помочь? Или я неправильно подхожу к проблеме?