Котлин - сопрограммы с петлями - PullRequest
1 голос
/ 02 октября 2019

Итак, у меня есть простой алгоритм, который следующим образом следует древовидной структуре:

Simple tree

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

Иногда узел может быть подключен к более чем одному узлу.

В моей текущей реализации алгоритм следует каждый путь разделения до конца перед завершением остальной части дерева:

Split tree

Это неоптимально,так как все остальные ветви должны ждать завершения алгоритма, что является большой потерей времени, особенно если дерево очень большое.

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

В настоящее время я новичок в сопрограммах Котлина, поэтому, пожалуйста, потерпите меня, если это покажется глупым.

В настоящее время я думаю реализовать это в следующемспособ использования сопрограмм Котлина (Примечание: это приблизительный код):

suspend fun propagate(startFromNode: Node) {
   coroutineScope {
      while (true) {
        //Do propagation
        if (split) {
           launch {
              propagate(splitNode)
           }
        }
        if (atEndOfPath) {
           break
        }
      }
   }
}

Я не уверен, как Котлин обрабатывает ситуацию, когда сопрограммы могут также порождать новые сопрограммы.

Если одна сопрограмма выдает исключениепо какой-то причине будут ли отменены все другие сопрограммы, которые происходят из этой основной области сопрограмм, включая сопрограммы, которые были запущены другими сопрограммами?

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

Спасибо.

1 Ответ

1 голос
/ 02 октября 2019

Подробнее об этом можно узнать, прочитав о структурированном параллелизме. Но чтобы ответить на ваши непосредственные вопросы.

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

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

...