Hello, I am writing an R interface for one of my C++ programs. The computations in C++ are very time consuming (several hours), so the user needs to be able to interrupt them. Currently, the only way I found to do so is calling R_CheckUserInterrupt() frequently. Unfortunately, there are several problems with that: 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. 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. 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? I would appreciate your advice on this topic. Best regards, Peter
On Apr 25, 2011, at 5:22 AM, schattenpflanze at arcor.de wrote:> Hello, > > I am writing an R interface for one of my C++ programs. The computations in C++ are very time consuming (several hours), so the user needs to be able to interrupt them. Currently, the only way I found to do so is calling R_CheckUserInterrupt() frequently. Unfortunately, there are several problems with that: > > 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.> 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(). 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.> 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. 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. Cheers, Simon
Peter, On 25/04/11 10:22, schattenpflanze at arcor.de wrote:> 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.Sorry not to have seen this thread sooner. You may like to give CXXR a try (http://www.cs.kent.ac.uk/projects/cxxr/). In CXXR the R interpreter is written in C++, and a user interrupt is handled by throwing a C++ exception, so the stack is unwound in an orderly fashion, destructors are invoked, etc. However, it's fair to say that in using CXXR with a multi-threaded program you'll be on the bleeding edge... Andrew
Andrew,> You may like to give CXXR a try > (http://www.cs.kent.ac.uk/projects/cxxr/). In CXXR the R interpreter is > written in C++, and a user interrupt is handled by throwing a C++ > exception, so the stack is unwound in an orderly fashion, destructors > are invoked, etc.Thank you for this suggestion. CXXR is a very interesting project! For my current project, however, I aim at distributing the program to other R users on pre-installed cluster nodes. Thus, I have no choice with respect to the underlying R interpreter. Best regards, Peter
Maybe Matching Threads
- checking user interrupts in C(++) code
- interrupting R from a GUI
- R_CheckUserInterrupt() can be a performance bottleneck within GUIs
- R_CheckUserInterrupt() can be a performance bottleneck within GUIs
- R_CheckUserInterrupt() can be a performance bottleneck within GUIs