({{, (RefLink[SetSharedVariable, paclet:ref/SetSharedVariable])[(Subscript[s, 1]),(Subscript[s, 2]),…] 
declares the symbols (Subscript[s, i]) as shared variables whose values are synchronized among all parallel kernels.}})

OpenersNotesSection(Spacer1)Details

The unique value of a shared variable is maintained by the master kernel and every access on a parallel subkernel is synchronized through the master kernel.

Shared variables without a value evaluate to (RefLink[Null, paclet:ref/Null]).

OpenersPrimaryExamplesSection(Spacer1)Examples  (14)

OpenersExampleSection0(Spacer1)Basic Examples  (1)

Make xs be a (global) shared variable:

xs=0;SetSharedVariable[xs];

Each subkernel increments the (global) shared variable value:

ParallelEvaluate[xs++]

xs

Without sharing, each subkernel has its own (local) copy of the variable:

xu=0; DistributeDefinitions[xu];

ParallelEvaluate[xu++]

xu

OpenersExampleSection1(Spacer1)Scope  (4)

Share a single value:

sv=17;SetSharedVariable[sv]

ParallelEvaluate[sv]

Access a single element of a shared list efficiently:

sl={a,b,c,d};SetSharedVariable[sl]

ParallelEvaluate[Part[Unevaluated[sl],$KernelID]]

Assign a new value to a shared variable:

SetSharedVariable[sx]

ParallelEvaluate[sx=$KernelID]

Only the last assignment performed remains:

sx

Change a single element of a shared list:

sl=Table[0,{$KernelCount}];SetSharedVariable[sl]

ParallelDo[sl[[i]]=$KernelID,{i,Length[sl]}]

sl

Update the value of a shared variable:

sx=0;SetSharedVariable[sx]

ParallelEvaluate[sx++]

ParallelEvaluate[sx*=2]

sx

Append to a shared list:

sl={};SetSharedVariable[sl]

ParallelEvaluate[AppendTo[sl,$KernelID]]

sl

Append to an element of a shared list:

sll=Table[{},{3}];SetSharedVariable[sll]

ParallelDo[AppendTo[sll[[i]],$KernelID],{i,Length[sll]}]

sll

OpenersExampleSection2(Spacer1)Generalizations & Extensions  (1)

Delayed values defined on the master kernel are evaluated on the master kernel:

SetSharedVariable[sx]

sx:=$KernelID

sx

ParallelEvaluate[sx]

Delayed values defined on a subkernel are evaluated on the kernel asking for the value:

SetSharedVariable[sy]

ParallelEvaluate[sy:=$KernelID,First[Kernels[]]]

sy

ParallelEvaluate[sy]

OpenersExampleSection3(Spacer1)Applications  (5)

Use shared variables to synchronize input and output in an infinite search:

n=1;primes={}; SetSharedVariable[n,primes];

Find n such that n!+1 is prime, until the computation is manually aborted:

PrintTemporary[Dynamic[{n,primes}]];
CheckAbort[
ParallelEvaluate[While[True,
With[{n=n++},If[PrimeQ[n!+1],AppendTo[primes,n]]]]],
{n,primes}]

Use a shared variable to signal all evaluations to stop as soon as a prime has been found:

stop=False;SetSharedVariable[stop]

ParallelEvaluate[Module[{p,r=$Failed},While[!stop,
p=RandomPrime[4500];
If[PrimeQ[2^p-1],stop=True;r=p];
];r]]

Use a shared variable to hand out tasks to do:

n=100;SetSharedVariable[n]

evs=Table[ParallelSubmit[Module[{r=$Failed},While[r===$Failed,With[{p=Prime[n++]},If[PrimeQ[2^p-1],r=p]]];
r]],{$KernelCount}]

{res,ev,evs}=WaitNext[evs];
AbortKernels[];
{n,res}

Monitor the progress of a calculation, counting major calculation steps:

i=0;SetSharedVariable[i]

PrintTemporary[Dynamic[i]];
ParallelEvaluate[Module[{n},While[True,n=RandomInteger[1000];i++;If[PrimeQ[n!+1],Break[]]];n]]

Return results as they are found:

res={};SetSharedVariable[res]

ParallelDo[If[PrimeQ[2^Prime[p]-1],AppendTo[res,p]],{p,100}];
res

Watch the results appear in real time:

res={};
PrintTemporary[Dynamic[res]];
ParallelDo[If[PrimeQ[2^Prime[p]-1],AppendTo[res,p]],{p,500}];
res

OpenersExampleSection4(Spacer1)Properties & Relations  (1)

(RefLink[$KernelCount, paclet:ref/$KernelCount]) is effectively a shared variable:

$KernelCount

ParallelEvaluate[$KernelCount]

OpenersExampleSection5(Spacer1)Possible Issues  (2)

Separate read and write operations are not thread-safe:

n=0;SetSharedVariable[n]

ParallelEvaluate[n=n+1]

n

Use atomic updates for synchronization:

n=0;SetSharedVariable[n]

ParallelEvaluate[n++]

n

Alternatively, use (RefLink[CriticalSection, paclet:ref/CriticalSection]) to make a whole code section atomic:

n=0;SetSharedVariable[n];Clear[nlock]

ParallelEvaluate[CriticalSection[{nlock},n=n+1]]

n

Create a shared variable whose value is a large matrix:

list=RandomReal[1,{10^4,10^4}];
SetSharedVariable[list]

Accessing its elements causes the whole matrix to be transferred to the subkernels repeatedly:

AbsoluteTiming[ParallelEvaluate[Table[list[[i,$KernelID]],{i,4}]]]

Use (RefLink[Unevaluated, paclet:ref/Unevaluated]) to allow the special code for parts of shared variables to see the variable:

AbsoluteTiming[ParallelEvaluate[Table[Part[Unevaluated[list],i,$KernelID],{i,4}]]]

({{DocumentationFooterIconsRelatedFunction.png, ({{See Also}, {(RefLink[$SharedVariables, paclet:ref/$SharedVariables])  ▪  (RefLink[UnsetShared, paclet:ref/UnsetShared])  ▪  (RefLink[SetSharedFunction, paclet:ref/SetSharedFunction])  ▪  (RefLink[DistributeDefinitions, paclet:ref/DistributeDefinitions])  ▪  (RefLink[OwnValues, paclet:ref/OwnValues])}})}})

({{DocumentationFooterIconsRelatedGuide.png, ({{Related Guides}, {▪(RefLinkPlain[Parallel Computing, paclet:guide/ParallelComputing])}, {▪(RefLinkPlain[Resource Sharing in Parallel Computing, paclet:guide/ResourceSharingInParallelComputing])}, {▪(RefLinkPlain[Parallel Computation Setup & Configuration, paclet:guide/ParallelComputationSetupAndConfiguration])}, {▪(RefLinkPlain[Concurrency, paclet:guide/Concurrency])}})}})