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

Henrik Bengtsson hb at biostat.ucsf.edu
Fri Apr 5 21:23:53 CEST 2013


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);
  idx <- dev.cur();
  plot(1:10, col=i);
} # 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
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).



More information about the R-devel mailing list