From simon.urbanek at r-project.org  Fri Apr  5 23:44:38 2013
From: simon.urbanek at r-project.org (Simon Urbanek)
Date: Fri, 5 Apr 2013 14:44:38 -0700
Subject: [Rd] parallel: Race-condition concern regarding graphics
	devices in a multi-thread environment
In-Reply-To: <CAFDcVCTdH3wwXapM07UK=+biSC5ppS9pLdX+tLkAjT6UEFXzpA@mail.gmail.com>
References: <CAFDcVCTdH3wwXapM07UK=+biSC5ppS9pLdX+tLkAjT6UEFXzpA@mail.gmail.com>
Message-ID: <088FD5D2-2999-4765-A62B-5EE79B57945F@r-project.org>

Henrik,

there are no threads. Hence you're on the wrong track there, it has nothing to do with device numbers/devices.The device number will be the same in all processes and that's ok. The issue here really is which png() pack-end are you using? (You didn't say). Some back-ends (like X11) cannot be run in forked environment, so you can't use them. I don't use png() myself, but I do know that CairoPNG() from the Cairo package works when forked.

Cheers,
Simon


On Apr 5, 2013, at 12:23 PM, Henrik Bengtsson <hb at biostat.ucsf.edu> wrote:

> Hi,
> 
> I'm trying to figure out how to safely make sure that I close the same
> graphics device that I opened earlier in a thread (and not one opened
> by a parallel thread).  In a *single-thread* environment, one can do
> the following to open and close a device:
> 
> makePlot <- function(i) {
>  filename <- sprintf("foo%d.png", i);
>  png(filename);
>  idx <- dev.cur();
>  on.exit(dev.off(idx));
>  plot(1:10, col=i);
>  title(main=i);
>  filename;
> } # makePlot()
> 
> However, in a *multi-thread* environment, e.g.
> 
> res <- mclapply(1:4, FUN=makePlot, mc.cores=4);
> 
> the following race-condition problem may occur, because of the
> non-atomicity(?) of (i) png() and (ii) dev.cur():
> 
> 1. Thread #1: png("foo1.png")
> 2. Thread #2: png("foo2.png")
> 3. Thread #1: idx <- dev.cur();  # idx == 3
> 4. Thread #2: idx <- dev.cur();  # idx == 3 (same device!)
> ...
> 5. Thread #1: dev.off(idx); # Closes device #3
> 6. Thread #2: plot(1:10, col=2); # Trying to plot, which opens a new
> on-screen device (or to another active device) since device #3 is
> closed.
> 7. Thread #2: dev.off(idx) # Trying to close device #3, which is already closed.
> 
> On this topic, there are some clues/notes on concern in the vignette
> of the 'parallel' package, but not enough to answer my concerns/solve
> my problems.  Any other references/discussion on this (other that
> source code)?
> 
> 
> Q1. Is there already a built-in protection against the above race condition?
> 
> Q2. If not on Q1, is there a way/strategy to get hold of the device
> (index) for the graphics devices that was opened by png() without
> using dev.cur()?
> 
> If not on Q2, what about transitioning to have graphics device
> functions return the opened device (index) (cf. connections), e.g. idx
> <- png(...).  A quick look at ?png and ?x11 show that those functions
> does not return anything (although code inspections show that they may
> return something, but always NULL when I try).
> 
> 
> Comments?
> 
> Henrik
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 
> 



[Rd] parallel: Race-condition concern regarding graphics devices in a multi-thread environment
Simon Urbanek