Асинхронное программирование в R - PullRequest
3 голосов
/ 29 июня 2019

Обзор

Я пишу программу (на 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 Ответ

2 голосов
/ 01 июля 2019

Мне кажется, ваш звонок блокируется только при создании рабочих, но не на время реальной работы.Например, если сначала сделать 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, а загрузка ЦП все еще высока.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...