[Rcpp-devel] Interrupts in compiled code.
Thanks for pointing that out. I don't pretend to understand the reasons but that method seems to be much more responsive than the throw/catch method. It seems like the throw catch should be just as efficient, and should add very little overhead. It does not add overhead, but the R_CheckUserInterupt also does not appear to add significant overhead either. The throw method seems to take a very long time between when the interrupt is sent before the error is caught. Is there a way to speed up the throw/catch? -Andrew
On Wed, Dec 8, 2010 at 3:42 PM, Davor Cubranic <cubranic at stat.ubc.ca> wrote:
How about just using R_CheckUserInterrupt()? Davor On 2010-12-08, at 1:02 PM, Dirk Eddelbuettel wrote:
On 8 December 2010 at 13:41, Andrew Redd wrote: | I have an MCMC chain that runs entirely in c++ with Rcpp. It sometimes
runs
| for a vary long time and I want to interrupt it. Is there an efficient
easy
| way to include catching an interupt signal and either aborting or
returning
| results to that point? This might be understood well, if so I
apologize.
Great question. Here is a simple example that uses a standard C interrupt handler to set
a
standard C++ exception to abort:
----------------------------------------------------------------
#include <csignal>
#include <Rcpp.h>
void intHandler(int dummy=0) {
std::cerr << "In intHandler" << std::endl;
throw std::runtime_error("Interception caught");
}
RcppExport SEXP foo(void) {
try {
signal(SIGINT, intHandler);
signal(SIGKILL, intHandler);
while (true) {
sleep(1); // not doing much
}
return R_NilValue;
} catch(std::exception &ex) {
std::cerr << "In catch of std::exeception" << std::endl;
// here you insert some clenup
forward_exception_to_r(ex);
} catch(...) {
::Rf_error("c++ exception (unknown reason)");
}
return R_NilValue;
}
----------------------------------------------------------------
which I then quickly turned into a shared object, load and ran at the
command-line [1]
edd at max:/tmp/andrew$ PKG_CPPFLAGS=`r -e'Rcpp:::CxxFlags()'` PKG_LIBS=`r
-e'Rcpp:::LdFlags()'` R CMD SHLIB int2throw.cpp
ccache g++ -I/usr/share/R/include
-I/usr/local/lib/R/site-library/Rcpp/include -fpic -g -O3 -Wall -pipe -pedantic -Wno-variadic-macros -c int2throw.cpp -o int2throw.o
g++ -shared -o int2throw.so int2throw.o
-L/usr/local/lib/R/site-library/Rcpp/lib -lRcpp -Wl,-rpath,/usr/local/lib/R/site-library/Rcpp/lib -L/usr/lib64/R/lib -lR
edd at max:/tmp/andrew$ r -e'dyn.load("int2throw.so"); .Call("foo")'
^CIn intHandler
In catch of std::exeception
Error in cpp_exception(message = "Interception caught", class =
"std::runtime_error") :
Interception caught Execution halted edd at max:/tmp/andrew$ edd at max:/tmp/andrew$ After lauching it from the one-line littler (r) expression, I pressed
Ctrl-C
which then got us into the interrupt which threw the exception which lead
to
the end.
In Rscript it looks a little more orderly on the unwind:
edd at max:/tmp/andrew$ Rscript -e 'dyn.load("int2throw.so"); .Call("foo")'
C-c C-cIn intHandler
In catch of std::exeception
Error in cpp_exception(message = "Interception caught", class =
"std::runtime_error") :
Interception caught Calls: .Call -> cpp_exception Execution halted edd at max:/tmp/andrew$ Hope this helps, Dirk [1] Not sure why I didn't use inline today... -- Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
_______________________________________________ Rcpp-devel mailing list Rcpp-devel at lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20101208/391fed42/attachment.htm>