Приостановка IO-связанных и CPU-связанных функций в сопрограммах Котлина - PullRequest
2 голосов
/ 06 мая 2019

Выполнение функции, связанной с вводом-выводом (скажем, запрос данных из бэкэнда) в сопрограмме, дает мне преимущество в приостановке ее выполнения до тех пор, пока результат запроса не станет доступным, верно?Однако функция, связанная с процессором (например, анализ огромного текстового файла) ничего не «ждет», она просто выполняет большую работу.Итак, выполнение этого внутри сопрограммы НЕ дает мне преимущество приостановки его выполнения?Единственное (ценное) преимущество, которое дают мне сопрограммы, когда речь идет о функциях, связанных с процессором, - это возможность выбирать поток (или пул потоков), который будет заблокирован при выполнении функции, я прав?

Ответы [ 2 ]

2 голосов
/ 07 мая 2019

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

suspend fun findBigPrime(): BigInteger = 
    BigInteger.probablePrime(4096, Random())

Функции приостановки можно превратить в неблокирующую функцию потока, используя withContext, как показано ниже,

suspend fun findBigPrime(): BigInteger =
    withContext(Dispatchers.Default) {
        BigInteger.probablePrime(4096, Random())
    }

Это приводит к блокировке сопрограммы, запущенной из основного / вызывающего потока, но не самого потока.

https://medium.com/@elizarov/blocking-threads-suspending-coroutines-d33e11bf4761

2 голосов
/ 06 мая 2019

Итак, выполнение этого внутри сопрограммы НЕ дает мне преимущество приостановки его выполнения?

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

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

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

Использование Dispachers.IO или Dispatchers.Default имеет эффект только выбора другого пула потоков, да.

В случае IO пул будет порождать столько потоков, сколько необходимо, поскольку все они могут быть «заблокированы при вводе / выводе».

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

...