Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have the following code, schematically:

$runningLogFile = "data.txt";

If[FileExistsQ[$runningLogFile], Get[$runningLogFile], Export[$runningLogFile, "", "Text"];];

f[x_, y_] := Block[{},
    (*do some calculation*)
    (*put append result to $runningLogFile*)
]

LaunchKernels[$ProcessorCount];
DistributeDefinitions[...]; 
ParallelTable[f[x,y], {x, 1, 10}, {y, 0, 15}];

This code works well, except for the fact that very ocassionally (surprisingly few times in fact, but still annoying) two threads try to write the result out to $runningLogFile at the same time, and the results output get spliced together. Is there a way to do this in a thread safe manner? (perhaps similar to critical procedure in openmp)

share|improve this question
    
I guess you could do all the writing from one kernel, ParallelEvaluate[writetolog[msg], 1] –  ssch Dec 8 '12 at 14:46
    
or write to n different files and join at the end. –  Ajasja Dec 8 '12 at 15:19
add comment

1 Answer

up vote 12 down vote accepted

Use the function CriticalSection[{lck}, expr], for example:

CriticalSection[{logfileLock}, PutAppend[result, $runningLogFile]]

This way the result, if it's large, stays on its kernel. The other approach for synchronization is as ssch suggests, do things like this in the master kernel with shared functions, but then you need to ship the result from the subkernel to the master kernel. Another tool in the synchronization arsenal is the shared variable, which is a variable that exists on the master kernel but is visible to subkernels for reading and writing. Instead of storing a log in a file, you could store it in a shared variable, but this also has the drawback that the value must be sent between master and subkernel.

CriticalSection and shared variables are documented in the Parallel Tools Virtual Shared Memory tutorial. SharedFunction is documented in the SharedFunction reference page.

share|improve this answer
    
logfileLock must be in a list, i.e. CriticalSection[{logfileLock}, ...]. –  WReach Dec 8 '12 at 16:20
    
@WReach: Thanks, I corrected the usage. –  Joel Klein Dec 8 '12 at 16:25
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.