[Rd] Race condition on parallel package's mcexit and rmChild
Simon Urbanek
@|mon@urb@nek @end|ng |rom R-project@org
Mon May 20 17:36:07 CEST 2019
Because that's the communication protocol between the parent and child. There is a difference between unsolicited exit and empty result exit.
Cheers,
Simon
> On May 20, 2019, at 11:22 AM, Sun Yijiang <sunyijiang using gmail.com> wrote:
>
> Have read the latest code, but I still don't understand why mc_exit
> needs to write zero on exit. If a child closes its pipe, parent will
> know that on next select.
>
> Best,
> Yijiang
>
> Tomas Kalibera <tomas.kalibera using gmail.com> 于2019年5月20日周一 下午10:52写道:
>>
>> This issue has already been addressed in 76462 (R-devel) and also ported
>> to R-patched. In fact rmChild() is used in mccollect(wait=FALSE).
>>
>> Best
>> Tomas
>>
>> On 5/19/19 11:39 AM, Sun Yijiang wrote:
>>> I've been hacking with parallel package for some time and built a
>>> parallel processing framework with it. However, although very rarely,
>>> I did notice "ignoring SIGPIPE signal" error every now and then.
>>> After a deep dig into the source code, I think I found something worth
>>> noticing.
>>>
>>> In short, wring to pipe in the C function mc_exit(SEXP sRes) may cause
>>> a SIGPIPE. Code from src/library/parallel/src/fork.c:
>>>
>>> SEXP NORET mc_exit(SEXP sRes)
>>> {
>>> int res = asInteger(sRes);
>>> ... ...
>>> if (master_fd != -1) { /* send 0 to signify that we're leaving */
>>> size_t len = 0;
>>> /* assign result for Fedora security settings */
>>> ssize_t n = write(master_fd, &len, sizeof(len));
>>> ... ...
>>> }
>>>
>>> So a pipe write is made in mc_exit, and here's how this function is
>>> used in src/library/parallel/R/unix/mcfork.R:
>>>
>>> mcexit <- function(exit.code = 0L, send = NULL)
>>> {
>>> if (!is.null(send)) try(sendMaster(send), silent = TRUE)
>>> .Call(C_mc_exit, as.integer(exit.code))
>>> }
>>>
>>> Between sendMaster() and mc_exit() calls, which are made in the child
>>> process, the master process may call readChild() followed by
>>> rmChild(). rmChild closes the pipe on the master side, and if it's
>>> called before child calls mc_exit, a SIGPIPE will be raised when child
>>> tries to write to the pipe in mc_exit.
>>>
>>> rmChild is defined but not used in parallel package, so this problem
>>> won't surface in most cases. However, it is a useful API and may be
>>> used by users like me for advanced control over child processes. I
>>> hope we can discuss a solution on it.
>>>
>>> In fact, I don't see why we need to write to the pipe on child exit
>>> and how it has anything to do with "Fedora security settings" as
>>> suggested in the comments. Removing it, IMHO, would be a good and
>>> clean way to solve this problem.
>>>
>>> Regards,
>>> Yijiang
>>>
>>> ______________________________________________
>>> 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
>
More information about the R-devel
mailing list