Hi, I've been thinking about how to handle c++ threads that were started via Rcpp calls to some of my c++ libraries from R. My main obstacle is trying to make sure that users don't try to process files that are being generated by a thread before the thread finishes. One thing I am considering is having my threaded code return a class to R that contains a pointer that it remembers. Then maybe I could just change the value at that pointer when my thread finishes. Does that seem like a reasonable approach? I'm not completely sure if this is related to your issue or not, but it might be similar enough to be worth asking... Thanks, Sean
On 4/26/11 9:21 AM, "Simon Urbanek" <simon.urba...@r-project.org> wrote: > > On Apr 26, 2011, at 7:30 AM, schattenpfla...@arcor.de wrote: > >> I have tested the solutions suggested by Simon and Thomas on a Linux machine. >> These are my findings: >> >>> On Windows you can look at the variable "UserBreak", available from >>> Rembedded.h. Outside of Windows, you can look at R_interrupts_pending, >>> available from R_ext/GraphicsDevice.h. R_ext/GraphicsDevice.h also has >>> R_interrupts_suspended, which you may or may not want to take into account, >>> depending on your use-case. >> I did not manage to get this to work. Neither R_interrupts_pending nor >> R_interrupts_suspended seem to change when I press ctrl+c. Perhaps this is >> due to the fact that I run R in a terminal without any graphical interface? >> > > Thomas' suggestion was not aimed at your problem - it was sort of the inverse > (more at your Qt question). If you want to interrupt R you can mess with those > flags and them let R run the event loop. It doesn't work in your (original) > case. > > >>> static void chkIntFn(void *dummy) { >>> R_CheckUserInterrupt(); >>> } >>> // this will call the above in a top-level context so it won't longjmp-out >>> of your context >>> bool checkInterrupt() { >>> return (R_ToplevelExec(chkIntFn, NULL) == FALSE); >>> } >>> // your code somewhere ... >>> if (checkInterrupt()) { // user interrupted ... } >> This solution works perfectly! It takes slightly longer to call this function >> than the plan R_CheckUserInterrupt() call, but in any reasonable scenario, >> the additional time is absolutely insignificant. >> >> Inside OpenMP parallel for constructs, one has to make sure that only the >> thread satisfying omp_get_thread_num()==0 makes the call (the 'master' >> construct cannot be nested inside a loop). I can then set a flag, which is >> queried by every thread in every loop cycle, causing fast termination of the >> parallel loop. After the loop, I throw an exception. Thus, my code is >> terminated gracefully with minimal effort. I can do additional cleanup >> operations (which usually is not necessary, since I use smart pointers), and >> report details on the interrupt to the user. >> >> With my limited testing, so far I have not noticed any downsides. Of course, >> there is the obvious drawback of not being supported officially (and thus >> maybe being subject to change), > > Actually, it is in the official API (Rinternals.h) so I don't think that is > the issue. > > >> the question of portability, and the question of interoperability with other >> errors. >> > > It is portable as well, so I'd say the main concern is what happens when > events trigger something that is not related to you and you eat those errors. > They will act as user-interrupt to you even if it's not what the user > intended. One could argue that it's the lesser of the evils, because if you > don't do anything R will just block so those events would have to wait until > you're done anyway. > > >> Moreover, I have found an old thread discussing almost the same topic: >> http://tolstoy.newcastle.edu.au/R/e4/devel/08/05/1686.html . >> The thread was created in 2008, so the issue is not really a new one. The >> solution proposed there is actually the same as the one suggested by Simon, >> namely using R_ToplevelExec(). >> > > Interesting - I'm glad Luke also suggested C-level onexit bac then - it is > something I was thinking about before .. > > Cheers, > Simon > > >> An officially supported, portable solution would of course be much >> appreciated! >> >> >> Best regards, >> Peter >> >> > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel