user8401743
user8401743

Reputation: 100

How to stop an R program using Rcpp midway in Rstudio on MacOS?

I have an R project which uses Rcpp for long simulations. When I try to stop such a program (e.g. it is taking too long or I am no longer interested in those results) using in Rstudio, then Rstudio crashes. Essentially I am looking for a way to kill the Rcpp function without crashing Rstudio so that I can run it again with some different parameters without losing variables in the R environment (when R studio crashes). I can save and load the environment before calling the function but I am hoping there might be an elegant solution. Any suggestions?

Here is an example.

testR <- function(){
    i=1  
    while(i>0){}}

Another function in a C++ file

// [[Rcpp::export]]
int testCpp( ) {
  double x=3;
  do{
  } while (x>0);
  return x;
}

When I call testR and then click on the red stop icon in the console then it exits normally. Instead, if I call testCpp and do the same I receive the following message (I have to press the red stop icon twice as nothing happens if I click it only once). If I click yes, the session is restarted and I lose the variables. enter image description here

""

Upvotes: 0

Views: 731

Answers (1)

Kevin Ushey
Kevin Ushey

Reputation: 21285

You can use Rcpp::checkUserInterrupt(). For example:

#include <unistd.h>
#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void forever() {

  try
  {
    for (int i = 0; ; i++)
    {
      Rcout << "Iteration: " << i << std::endl;
      ::sleep(1);
      Rcpp::checkUserInterrupt();
    }
  }
  catch (Rcpp::internal::InterruptedException& e)
  {
    Rcout << "Caught an interrupt!" << std::endl;
  }

}

/*** R
forever()
*/

If you attempt to interrupt R while this is running you should see something like:

> Rcpp::sourceCpp('scratch/interrupt.cpp')
> forever()
Iteration: 0
Iteration: 1
Iteration: 2

Caught an interrupt!

Note that the try-catch block is unnecessary if you're using Rcpp attributes as the associated try-catch exception handlers will automagically be generated in a wrapper function for you. I just add them here to illustrate that Rcpp responds to interrupts with this API by throwing a special exception.

Upvotes: 4

Related Questions