Асинхронное программирование в R

обзор

Я пишу программу (на R), которая выполняет вызовы API в определенное время. Вызовы API занимают некоторое время, но мне нужно, чтобы таймер (основной цикл) продолжал считать, пока выполняется вызов API. Для этого мне нужно "передать" вызов API другому потоку ЦП. Я считаю, что это возможно, и посмотрел в future а также promises пакеты, но пока не нашли решения.

Воспроизводимый пример

Давайте запустим for цикл, который насчитывает от 0 до 100. Когда счетчик (i) достигает 50, он должен завершить ресурсоемкий процесс (вызов функции samplerкоторый отбирает 1 миллион нормальных распределений 10000 раз ради занимаемого пространства вычислений). Желание, чтобы счетчик продолжал считать, пока sampler() делает свою работу в другом потоке.

#Something to take up computation space
sampler <- function(){
  for(s in 1:10000) sample(1000000)
}

#Get this counter to continue while sampler() runs on another thread
for(i in 1:100){
  message(i)
  if(i == 50){
    sampler()
  }
}

Что я пробовал (безуспешно)

library(future)

sampler <- function(){
  for(s in 1:10000) sample(1000000)
}

for(i in 1:100){
  message(i)
  if(i == 50){
    mySamples <- future({ sampler() }) %plan% multiprocess
  }
}

1 ответ

Решение

Мне кажется, ваш звонок блокируется только при создании рабочих, но не на время реальной работы. Например, если сделать plan() во-первых, счетчик не будет блокировать:

library(future)

sampler <- function(){
  for(s in 1:10000) sample(1000000)
}

plan(multiprocess)

for(i in 1:100){
  message(i)
  if(i == 50){
    mySamples <- future({ sampler() })
  }
}

Также обратите внимание, что время выполнения sampler() намного длиннее, чем продолжительность блокирующего вызова в вашем коде, и что после выполнения вашего кода mySamples все еще имеет статус resolved: FALSE и загрузка процессора все еще высока.

Другие вопросы по тегам