[Rd] [External] Re: Background R session on Unix and SIGINT

Simon Urbanek @|mon@urb@nek @end|ng |rom R-project@org
Wed May 1 16:02:41 CEST 2019


Gabor,

I think you're talking about two independent things. You can interrupt the computation, no question about that. It's just that if you send an interrupt while you're *not* doing any computations, it will be signaled but not raised until the interrupts are checked since there is no one to check it. This goes back to my original response - the interactive REPL calls R_CheckUserInterrupt(), but the straight stdin-prcessing doesn't (since it's expected to be a script, not interactive prompt). If you just want to clear interrupts before next processing you can either just run R_CheckUserInterrupt() explicitly, or on R side do anything that does that, e.g. to take your example "tryCatch(Sys.sleep(0), interrupt = function(e) e)" will clear it.

Cheers,
Simon


> On Apr 30, 2019, at 7:03 PM, Gábor Csárdi <csardi.gabor using gmail.com> wrote:
> 
> Unfortunately --interactive also makes the session interactive(),
> which is bad for me, as it is a background session.
> 
> In general, I don't want the interactive behavior, but was wondering
> if I could send as SIGINT to try to interrupt the computation of the
> background process, and if that does not work, then I would send a
> SIGKILL and start up another process. It all works nicely, except for
> this glitch, but I think I can work around it.
> 
> Thanks,
> Gabor
> 
> On Tue, Apr 30, 2019 at 10:55 PM Tierney, Luke <luke-tierney using uiowa.edu> wrote:
>> 
>> A Simon pointed out the interrupt is recorded but not processed until
>> a safe point.
>> 
>> When reading from a fifo or pipe R runs non-interactive, which means
>> is sits in a read() system call and the interrupt isn't seen until
>> sometime during evaluation when a safe checkpoint is reached.
>> 
>> When reading from a terminal R will use select() to wait for input and
>> periodically wake and check for interrupts. In that case the interrupt
>> will probably be seen sooner.
>> 
>> If the interactive behavior is what you want you can add --interactive
>> to the arguments used to start R.
>> 
>> Best,
>> 
>> luke
>> 
>> On Tue, 30 Apr 2019, Gábor Csárdi wrote:
>> 
>>> OK, I managed to create an example without callr, but it is still
>>> somewhat cumbersome. Anyway, here it is.
>>> 
>>> Terminal 1:
>>> mkfifo fif
>>> R --no-readline --slave --no-save --no-restore < fif
>>> 
>>> Terminal 2:
>>> cat > fif
>>> Sys.getpid()
>>> 
>>> This will make Terminal 1 print the pid of the R process, so we can
>>> send a SIGINT:
>>> 
>>> Terminal 3:
>>> kill -INT pid
>>> 
>>> The R process is of course still running happily.
>>> 
>>> Terminal 2 again:
>>> tryCatch(Sys.sleep(10), interrupt = function(e) e)
>>> 
>>> and then Terminal 1 prints the interrupt condition:
>>> <interrupt: >
>>> 
>>> This is macOS and 3.5.3, although I don't think it matters much.
>>> 
>>> Thanks much!
>>> G.
>>> 
>>> On Tue, Apr 30, 2019 at 9:50 PM Simon Urbanek
>>> <simon.urbanek using r-project.org> wrote:
>>>> 
>>>> Can you give an example without callr? The key is how is the process stated and what it is doing which is entirely opaque in callr.
>>>> 
>>>> Windows doesn't have signals, so the process there is entirely different. Most of the WIN32 processing is event-based.
>>>> 
>>>> Cheers,
>>>> Simon
>>>> 
>>>> 
>>>>> On Apr 30, 2019, at 4:17 PM, Gábor Csárdi <csardi.gabor using gmail.com> wrote:
>>>>> 
>>>>> Yeah, I get that they are async.
>>>>> 
>>>>> What happens is that the background process is not doing anything when
>>>>> the process gets a SIGINT. I.e. the background process is just
>>>>> listening on its standard input.
>>>>> 
>>>>> AFAICT for an interactive process such a SIGINT is just swallowed,
>>>>> with a newline outputted to the terminal.
>>>>> 
>>>>> But apparently, for this background process, it is not swallowed, and
>>>>> it is triggered later. FWIW it does not happen on Windows, not very
>>>>> surprisingly.
>>>>> 
>>>>> Gabor
>>>>> 
>>>>> On Tue, Apr 30, 2019 at 9:13 PM Simon Urbanek
>>>>> <simon.urbanek using r-project.org> wrote:
>>>>>> 
>>>>>> Interrupts are not synchronous in R - the signal only flags the request for interruption. Nothing actually happens until R_CheckUserInterrupt() is called at an interruptible point. In you case your code is apparently not calling R_CheckUserInterrupt() until later as a side-effect of the next evaluation.
>>>>>> 
>>>>>> Cheers,
>>>>>> Simon
>>>>>> 
>>>>>> 
>>>>>>> On Apr 30, 2019, at 3:44 PM, Gábor Csárdi <csardi.gabor using gmail.com> wrote:
>>>>>>> 
>>>>>>> Hi All,
>>>>>>> 
>>>>>>> I realize that this is not a really nice reprex, but anyone has an
>>>>>>> idea why a background R session would "remember" an interrupt (SIGINT)
>>>>>>> on Unix?
>>>>>>> 
>>>>>>> rs <- callr::r_session$new()
>>>>>>> rs$interrupt()     # just sends a SIGINT
>>>>>>> #> [1] TRUE
>>>>>>> 
>>>>>>> rs$run(function() 1+1)
>>>>>>> #> Error: interrupt
>>>>>>> 
>>>>>>> rs$run(function() 1+1)
>>>>>>> #> [1] 2
>>>>>>> 
>>>>>>> It seems that the main loop somehow stores the SIGINT it receives
>>>>>>> while it is waiting on stdin, and then it triggers it when some input
>>>>>>> comes in.... Maybe. Just speculating....
>>>>>>> 
>>>>>>> Thanks,
>>>>>>> Gabor
>>>>>>> 
>>>>>>> ______________________________________________
>>>>>>> R-devel using r-project.org mailing list
>>>>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>>>>> 
>>>>>> 
>>>>> 
>>>> 
>>> 
>>> ______________________________________________
>>> R-devel using r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>> 
>> 
>> --
>> Luke Tierney
>> Ralph E. Wareham Professor of Mathematical Sciences
>> University of Iowa                  Phone:             319-335-3386
>> Department of Statistics and        Fax:               319-335-3017
>>    Actuarial Science
>> 241 Schaeffer Hall                  email:   luke-tierney using uiowa.edu
>> Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu
> 



More information about the R-devel mailing list