Предположим, у меня есть неориентированный граф.
Небольшая часть графика:
A -----\
C
B -----/
Теперь узлы A и B приступают к параллельной модификации узла C. // Узел A и узел B обрабатывают узел C в параллельном потоке.
Я хочу, чтобы поток для Узла Б ожидал завершения потока для Узла А.
Так должно быть. Другого пути нет.
Я также не хочу, чтобы другие потоки, которые обрабатывают другие узлы, ожидали вышеуказанного условия, то есть я не хочу использовать мьютекс.
Я создал логический флаг члена класса и хочу использовать его как условие. // пусть это
флаг быть d_flag
MT здесь использует несколько процессоров.
Решение, которое я думаю, не работает:
while (d_flag) {
// busy waiting
}
d_flag = true;
// Critical Section
d_flag = false;
while (d_flag) {
// busy waiting
}
d_flag = true;
// Critical Section
d_flag = false;
Насколько я понимаю, если в многопроцессорном процессоре нода A работает на CPU1, а нод B — на CPU 2, спин-блокировка побеждена.
Может возникнуть условие, когда цикл while оценивается как false, поскольку тест в цикле while больше не является атомарным.
Правильно ли мое понимание ????? Если да, то есть ли решение без использования общего мьютекса.
Я бы предложил создать условную ветвь, которая выполняется только тогда, когда обрабатываемый узел равен C. В этой ветке вы можете настроить условную переменную для потока узла B, чтобы он ожидал, пока поток узла A не завершил обработку узла C. Предполагая, что вы знаете поток Идентификаторы, связанные с узлами, я мог бы представить, что это довольно легко реализовать (по крайней мере, наивно). Возможно, вы захотите реализовать условную переменную с таймаутом, если вы не уверены, что поток узла A когда-нибудь завершит обработку узла C.
Если я могу сделать предложение, ваш вариант использования, имеющий ограничения на порядок операций над узлами для определенных потоков, предполагает, что вы можете рассмотреть парадигму параллельного программирования, которая позволяет вам выражать эти идеи на более высоком уровне абстракции. Возможно, использование актерского паттерна поможет?
Вот реализация, которую я считаю довольно хорошей для C ++:
https://github.com/Neverlord/libcppa
Используя такой шаблон, вы могли бы, чтобы ваши субъекты (потоки) сообщали о том, какие узлы они обработали, и управляли своим потоком на основе этих сообщений. Так, например, вы могли бы, чтобы субъект узла A информировал субъекта B, когда он завершил обработку узла C. Это позволяет субъекту узла B делать другие вещи, ожидая сообщения от A.