[Rd] Interrupting C++ code execution
schattenpflanze at arcor.de
schattenpflanze at arcor.de
Mon Apr 25 17:09:08 CEST 2011
Thank you for your response, Simon.
>> 1. Calling R_CheckUserInterrupt() interrupts immediately, so I have
>> no possibility to exit my code gracefully. In particular, I suppose
>> that objects created on the heap (e.g., STL containers) are not
>> destructed properly.
> In general, you're responsible for the cleanup. See R-devel archives
> for discussion on the interactions of C++ and R error handling.
> Generally, you should not use local objects and you should use
> on.exit to make sure you clean up.
I am using Rcpp (Rcpp-modules, to be precise). This means, I do actually
not write any R code. Moreover, the C++ code does not use the R API. My
C++ functions are 'exposed' to R via Rcpp, which creates suitable S4
classes. Rcpp does the exception handling.
In particular, there is no obvious possibility for me to add an
'on.exit' statement to a particular exposed C++ method.
> Generally, you should not use local objects
We are talking about large amounts of code, dozens of nested function
calls, and even external libraries. So "not using local objects" is
definitely no option.
>> 2. Calling R_CheckUserInterrupt() within a parallel OpenMP loop
>> causes memory corruptions. Even if I do so within a critical
>> section, it usually results in segfaults, crashes, or invalid
>> variable contents afterwards. I suppose this is due to the threads
>> not being destroyed properly. Since most of the time critical
>> computations are done in parallel, this means I can hardly
>> interrupt anything.
> As you know R is not thread-safe so you cannot call any R API from a
> thread - including OMP threads - so obviously you can't call
> R_CheckUserInterrupt().
That is very interesting. Not being thread safe does not necessarily
imply that a function cannot be called from within a thread (as long as
it is not done concurrently from several threads). In particular, the
main program itself is also a thread, isn't it?
Since no cleanup is done, however, it is now clear that calling
R_CheckUserInterrupt() _anywhere_ in my program, parallel section or
not, is a bad idea.
> Since you're using threads the safe way is to
> perform your computations on a separate thread and let R handle
> events so that you can abort your computation thread as part of
> on.exit.
Starting the computations in a separate thread is a nice idea. I could
then call R_CheckUserInterrupt() every x milliseconds in the function
which dispatches the worker thread. Unfortunately, I see no obvious way
of adding an "on.exit" statement to an Rcpp module method. So I would
probably have to call an R function from C++ (e.g., using RInside) which
contains the on.exit statement, which in turn calls again a C++ function
setting a global 'abort' flag and waits for the threads to be
terminated. Hmmm.
How does on.exit work? Could I mimic that behaviour directly in C++?
>> Having a function similar to R_CheckUserInterrupt() but returning a
>> boolean variable (has an interrupt occurred or not?) would solve
>> these problems. Is there a way to find out about user interrupt
>> requests (the user pressing ctrl+c or maybe a different set of
>> keys) without interrupting immediately?
> Checking for interrupts may involve running the OS event loop (to
> allow the user to interact with R) and thus is not guaranteed to
> return.
I see.
> There is no general solution - if you're worried only about
> your, local code, then on unix, for example, you could use custom
> signal handlers to set a flag and co-operatively interrupt your
> program. On Windows there is the UserBreak flag which can be set by a
> separate thread and thus you may check on it. That said, all this is
> very much platform-specific.
Being able to set a flag is all I need and would be the perfect solution
imho. However, I do not yet see how I could achieve that.
How can I write a signal handler within C++ code which does not create a
GUI and has no dedicated event dispatching thread?
Would it be possible to use, e.g., a Qt keyboard event handler within
the C++ code? Would a keyboard event be visible to such an event
handler? Is it not intercepted by R / the terminal window / the OS?
Does any existing R package contain signal handlers?
Best regards,
Peter
More information about the R-devel
mailing list