0

I have the following code to burn all CPU on all cores:

<#
.SYNOPSIS
Script similar to BurnCpu Chaos Monkey

.DESCRIPTION
Using the largest int32 positive integer, this script calculates the factorial to generate 100% CPU utilisation.
The script fills all CPUs.

Source ForEach-Parallel: https://powertoe.wordpress.com/2012/05/03/foreach-parallel/
Source maxin out CPU of single core: https://dthomo.wordpress.com/2012/04/19/use-powershell-to-max-out-cpu-usage/

.EXAMPLE
Chaos-BurnCPU

#>.

function ForEach-Parallel {
    param(
        [Parameter(Mandatory=$true,position=0)]
        [System.Management.Automation.ScriptBlock] $ScriptBlock,
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [PSObject]$InputObject,
        [Parameter(Mandatory=$false)]
        [int]$MaxThreads=5
    )
    BEGIN {
        $iss = [system.management.automation.runspaces.initialsessionstate]::CreateDefault()
        $pool = [Runspacefactory]::CreateRunspacePool(1, $maxthreads, $iss, $host)
        $pool.open()
        $threads = @()
        $ScriptBlock = $ExecutionContext.InvokeCommand.NewScriptBlock("param(`$_)`r`n" + $Scriptblock.ToString())
    }
    PROCESS {
        $powershell = [powershell]::Create().addscript($scriptblock).addargument($InputObject)
        $powershell.runspacepool=$pool
        $threads+= @{
            instance = $powershell
            handle = $powershell.begininvoke()
        }
    }
    END {
        $notdone = $true
        while ($notdone) {
            $notdone = $false
            for ($i=0; $i -lt $threads.count; $i++) {
                $thread = $threads[$i]
                if ($thread) {
                    if ($thread.handle.iscompleted) {
                        $thread.instance.endinvoke($thread.handle)
                        $thread.instance.dispose()
                        $threads[$i] = $null
                    }
                    else {
                        $notdone = $true
                    }
                }
            }
        }
    }
}

# Burn CPU of all cores.
$numberOfCores = (Get-WmiObject -Class win32_processor).NumberOfCores
(0..$numberOfCores) | ForEach-Parallel -MaxThreads $numberOfCores {
    foreach ($number in 1..2147483647) { 
        $result = $result * $number 
    }
}

Unfortunately, when the script is stopped the process keeps running and keeps up 100% CPU until we kill the process. How can we accomplish that the END is run in the ForEach-Parallel function or in an other way accomplish the threads are cleaned up?

1 Answer 1

2

Here's a slightly different approach to using runspaces:

Invoke-ScriptAsynch

That lets you specify a timeout on the runspaces. It also allows you to preserve information in the output streams of powershell instances. You could have your script write it's process ID ($PID) to the Verbose or Debug stream, and use that to script killing the processes.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.