Collecting output produced by threads
$threads = @()
foreach ($t in 'seven', 'eight-three', 'three', 'forty-eight', 'nine', 'one-hundred', 'twelve') {
$threads += start-threadJob {
param($arg)
start-sleep (get-random -maximum 10)
return "$arg has $($arg.length) characters"
} -argumentList $t
}
#
# Wait until threads are finished
#
$null = wait-job -job $threads
foreach ($thread in $threads) {
receive-job $thread
}
Starting jobs with and without a mutex
The following example tries to demonstrate how using a
System.Threading.Mutex
object prevents race conditions.
Change the value of the variable $useMutex
to either use or not use the mutex:
$shared = @{accu = 0}
$nofThreads = 10
$threads = @()
for ($t = 0; $t -lt $nofThreads; $t++) {
$threads += start-threadJob {
$useMutex = $false ### Change here! ###
if ($useMutex) {
[bool] $newMutex = $false
$mtx = new-object System.Threading.Mutex($true, 'tq84-mtx', [ref] $newMutex)
}
for ($i = 0; $i -lt 10 ; $i++) {
$shared = $using:shared
if ($useMutex) {
$mtx.WaitOne()
}
$accu_ = $shared.accu
$accu_ = $accu_ + 1
start-sleep -milliseconds 1 # Give race condition more chance to occur
$shared.accu = $accu_
if ($useMutex) {
$mtx.RelaseMutex()
}
$cur ++
}
}
}
$t = 0
while ($t -lt $nofThreads) {
if ($threads[$t].state -eq 'Completed') {
$t++
}
else {
start-sleep 1
}
}
write-host "accu = $($shared.accu)"