Henrik Bengtsson
2025-May-11 17:58 UTC
[Rd] Is it possible to gracefully interrupt a child R process on MS Windows?
In help("pskill", package = "tools") is says: Only SIGINT and SIGTERM will be defined on Windows, and pskill will always use the Windows system call TerminateProcess. As far as I understand it, TerminateProcess [1] terminates the process "quite abruptly". Specifically, it is not possible for the process to intercept the termination and gracefully shutdown. In R terms, we cannot rely on: tryCatch({ ... }, interrupt = function(int) { ## cleanup }) Similarly, it does not look like R itself can exit gracefully. For example, when signalling pskill(pid, signal = SIGINT) to another R process, that R process leaves behind its tempdir(). In contrast, if the user interrupts the process interactively (Ctrl-C), there is an 'interrupt' condition that can be caught, and R cleans up after itself before exiting. QUESTION: Is it possible to gracefully interrupt a child R process on MS Windows, e.g. a PSOCK cluster node? (I don't think so, but I figure it's worth asking) SUGGESTIONS: Also, if my understanding that TerminateProcess is abrupt is correct, and there is no way to exit gracefully, would it make sense to clarify this fact in help("pskill", package = "tools")? Right now you either have to know how 'TerminateProcess' works, or run various tests on MS Windows to figure out the current behavior. Also, would a better signal mapping be: Only SIGKILL will be defined on Windows, and pskill will always use the Windows system call TerminateProcess. Signals SIGINT and SIGTERM are supported for backward compatible reasons, but are effectively identical to SIGKILL. ? That would change the expectations on what will happen for people coming from the POSIX world. [1] https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminateprocess /Henrik
Ivan Krylov
2025-May-11 21:37 UTC
[Rd] Is it possible to gracefully interrupt a child R process on MS Windows?
On Sun, 11 May 2025 10:58:18 -0700 Henrik Bengtsson <henrik.bengtsson at gmail.com> wrote:> Is it possible to gracefully interrupt a child R process on MS > Windows, e.g. a PSOCK cluster node?Not in the general case (I think, based on the code paths leading to Rf_onintr() on Windows), but PSOCK cluster nodes are instances of Rscript.exe running the terminal front-end, and the terminal front-end interrupts R upon receipt of Ctrl+C and Ctrl+Break console events: https://learn.microsoft.com/en-us/windows/console/setconsolectrlhandler This makes it possible for ps::ps_interrupt() to spawn a child process to attach to the console where Rscript.exe is running and generate this event: https://github.com/r-lib/ps/blob/042d4836ac584c95a59985171fdfa3b6baf2fa6c/src/interrupt.c#L33-L35 This probably needs specially written code in the children that expects to be interrupted in order to work reliably, but interrupting the children and then interrupting the parent and submitting another job to the PSOCK cluster seems to have worked for me on R-4.5.0. -- Best regards, Ivan
Tomas Kalibera
2025-May-12 07:57 UTC
[Rd] Is it possible to gracefully interrupt a child R process on MS Windows?
I think for reliability and portability of termination, one needs to implement an application-specific termination protocol on both ends. Only within specific application constraints, one can also define what graceful termination means. Typically, one also has other expectations from the termination process - such that the processes will terminate in some finite time/soon. In some cases one also may require certain behavior of the cleanup code (such as that wouldn't take long, wouldn't do some things, etc), to meet the specific termination requirements. And it may require some behavior of the non-cleanup code as well (such as polling in some intervals). Using signals to terminate a process even on Unix may not be seen as graceful enough, either. It is not just a Windows problem. Yes, TerminateProcess() on Windows will not allow the target process to run any cleanup. The documentation of "pskill" names "TerminateProcess()" explicitly so that the readers interested in the details can follow Microsoft documentation. But I think one should avoid using pskill()/signals for termination and instead use an application-level termination protocol. The parallel package, PSOCK, has one, based on socket connections, so perhaps one can take some inspiration from there. Best Tomas On 5/11/25 19:58, Henrik Bengtsson wrote:> In help("pskill", package = "tools") is says: > > Only SIGINT and SIGTERM will be defined on Windows, and pskill will > always use the Windows system call TerminateProcess. > > As far as I understand it, TerminateProcess [1] terminates the process > "quite abruptly". Specifically, it is not possible for the process to > intercept the termination and gracefully shutdown. In R terms, we > cannot rely on: > > tryCatch({ > ... > }, interrupt = function(int) { > ## cleanup > }) > > Similarly, it does not look like R itself can exit gracefully. For > example, when signalling pskill(pid, signal = SIGINT) to another R > process, that R process leaves behind its tempdir(). In contrast, if > the user interrupts the process interactively (Ctrl-C), there is an > 'interrupt' condition that can be caught, and R cleans up after itself > before exiting. > > QUESTION: > > Is it possible to gracefully interrupt a child R process on MS > Windows, e.g. a PSOCK cluster node? (I don't think so, but I figure > it's worth asking) > > > SUGGESTIONS: > > Also, if my understanding that TerminateProcess is abrupt is correct, > and there is no way to exit gracefully, would it make sense to clarify > this fact in help("pskill", package = "tools")? Right now you either > have to know how 'TerminateProcess' works, or run various tests on MS > Windows to figure out the current behavior. > > Also, would a better signal mapping be: > > Only SIGKILL will be defined on Windows, and pskill will always use > the Windows system call TerminateProcess. Signals SIGINT and SIGTERM > are supported for backward compatible reasons, but are effectively > identical to SIGKILL. > > ? That would change the expectations on what will happen for people > coming from the POSIX world. > > [1] https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminateprocess > > /Henrik > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel
Reasonably Related Threads
- Is it possible to gracefully interrupt a child R process on MS Windows?
- Detecting whether a process exists or not by its PID?
- BUG: tools::pskill() returns incorrect values or non-initated garbage values [PATCH]
- Detecting whether a process exists or not by its PID?
- Detecting whether a process exists or not by its PID?