如何终止停止在PowerShell脚本中启动的线程 [英] How to kill threads started in PowerShell script on stop

查看:430
本文介绍了如何终止停止在PowerShell脚本中启动的线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码来刻录所有内核上的所有CPU:

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 
    }
}

不幸的是,当脚本停止运行时,进程将继续运行并占用100%的CPU,直到我们终止进程为止.如何才能使END在ForEach-Parallel函数中运行,或者以其他方式完成对线程的清理?

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?

推荐答案

使用运行空间的方法略有不同:

Here's a slightly different approach to using runspaces:

Invoke-ScriptAsynch

这使您可以在运行空间上指定超时.它还允许您将信息保留在Powershell实例的输出流中.您可以让脚本将其进程ID($ PID)写入到Verbose或Debug流中,然后使用该脚本来脚本杀死进程.

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.

这篇关于如何终止停止在PowerShell脚本中启动的线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆