Powershell 并发任务 | Runspace 线程 | 结果获取

介绍

在 PowerShell 中进行多任务处理(Multithreading 或 Parallel Processing)主要目的是提高脚本的执行效率和性能。对于需要处理大量数据或执行多个独立任务的脚本来说尤其有用。

  1. 提高性能: 多任务处理允许脚本同时执行多个任务,从而加快整体执行速度。对于需要处理大型数据集或执行耗时的操作时尤为重要。

  2. 充分利用多核处理器: 现代计算机配备了多核处理器。通过多任务处理,可以充分发挥这些多核处理器的性能,提高整体计算能力。

  3. 并行执行独立任务: 在某些情况下,脚本需要执行多个相互独立的任务。多任务处理使得这些任务可以同时进行,而不是依次执行,提高脚本的效率。

  4. 提高响应性: 脚本需要响应用户输入或事件,多任务处理可以确保主线程(通常是用户界面线程)保持响应,而后台线程处理其他任务。

  5. 资源分配: 多任务处理允许更灵活地分配系统资源,例如内存、CPU 时间等,以满足不同任务的需求。

Runspace

在 PowerShell 中,使用 PowerShell Jobs、Runspace 等技术来实现多任务处理。
本文使用 Runspace,Runspace 是 PowerShell 中用于实现多任务处理的一种机制,其优势主要体现在以下几个方面:

  1. 轻量级: Runspace 是一种轻量级的线程池技术,相较于创建完整的 PowerShell 进程或 Runspace 进程,资源开销较小。在一个脚本中创建多个 Runspace,以执行并发任务而不过度消耗系统资源。

  2. 资源隔离: 每个 Runspace 拥有独立的 PowerShell 运行环境和内存空间,意味着一个 Runspace 的异常不会影响到其他 Runspace,提供了更好的资源隔离。

  3. 更好的性能: Runspace 同时执行多个任务,充分利用多核处理器和系统资源,从而提高整体脚本执行的性能。在需要处理大量数据或执行复杂任务时,Runspace 能够更高效地完成工作。

  4. 适用于并行处理: Runspace 是适用于并行处理的一种机制,同时执行多个任务,不是按顺序一个一个地执行。这对于需要并行处理独立任务的脚本非常有帮助。

  5. 异步执行: Runspace 可以用于实现异步执行任务,脚本可以继续执行而无需等待所有任务完成。这对于需要同时进行多个长时间运行的任务时尤为有用。

示例

# 开始时间
$StartTime = Get-Date
# 处理任务
$Worker = {
   
    param($Filename)
    Write-Host "Processing $filename"
    Start-Sleep -Seconds 1 # Doing some work....
    $Item = New-Item -Name $Filename
    Write-Output $Item.FullName
}
# 最大并发
$MaxRunspaces = 10

try {
   
	# 线程池
    $RunspacePool = [runspacefactory]::CreateRunspacePool(1, $MaxRunspaces)
    $RunspacePool.Open()

    $Jobs = New-Object System.Collections.ArrayList

    $Filenames = @("file1.txt", "file2.txt", "file3.txt", "file4.txt", "file5.txt", "file6.txt", "file7.txt", "file8.txt", "file9.txt", "file10.txt", "file11.txt")

    foreach ($File in $Filenames) {
   
        Write-Host "Creating runspace for $File"
        $PowerShell = [powershell]::Create()
        $PowerShell.RunspacePool = $RunspacePool
        $PowerShell.AddScript($Worker).AddArgument($File) | Out-Null
        
        $JobObj = New-Object -TypeName PSObject -Property @{
   
            Runspace   = $PowerShell.BeginInvoke()
            PowerShell = $PowerShell  
        }

        $Jobs.Add($JobObj) | Out-Null
    }

    while ($Jobs.Runspace.IsCompleted -contains $false) {
   
        Write-Host (Get-date).Tostring() "Still running..."
        Start-Sleep 1
    }
}
finally {
   
	# 始终关闭进程池
    $RunspacePool.Close()
}
# 结束时间
$endTime = Get-Date
# 运行时间
Write-Host "The script runs for Total time (s):$(($endTime - $StartTime).TotalSeconds)"
# 任务对象信息
$Jobs.powershell.Streams
$Jobs.powershell.haderrors

image.png
image.png

逻辑介绍

代码逻辑jiesh:

  1. 定义 Worker 脚本块:

    • $Worker 脚本块是一个用于处理文件的脚本块。接受一个文件名参数,输出处理后的结果。
  2. 设置并发 Runspaces 数量:

    • $MaxRunspaces 变量定义最大 Runspaces 数量,即同时处理的最大任务数。
  3. 创建 Runspace 池:

    • 使用 [runspacefactory]::CreateRunspacePool 创建 Runspace 池,设置最小和最大 Runspaces 数量,并打开池。
  4. 创建并发任务:

    • 使用 foreach 循环遍历文件名数组 $Filenames
    • 每个文件名创建一个 PowerShell 对象 $PowerShell
    • $Worker 脚本块添加到 PowerShell 中,并通过 AddArgument 传递文件名参数。
    • 使用 BeginInvoke 异步启动 PowerShell,返回一个 Runspace 对象。
    • 创建一个包含 Runspace 和 PowerShell 对象的自定义对象 $JobObj,并将其添加到 $Jobs 数组中。
  5. 等待任务完成:

    • 使用 while 循环检查所有任务是否完成。循环条件是检查 $Jobs.Runspace.IsCompleted 数组,确保所有任务都完成。
    • 在循环中使用 Start-Sleep 暂停一秒钟,以避免过于频繁的检查。
  6. 关闭 Runspace 池:

    • finally 块中关闭 Runspace 池,确保资源的正确释放。
  7. 输出结果和错误信息:

    • 输出所有任务的 Streams(输出、错误等)。
    • 输出是否有错误发生($Jobs.powershell.haderrors)。

这段代码通过并发处理多个文件,每个文件在一个独立的 Runspace 中执行,最终输出各任务的结果和错误信息。并发处理可以提高处理大量文件时的效率。

Ending


~喜欢的话,请收藏 | 关注(✪ω✪)~
~万一有趣的事还在后头呢,Fight!!(o^-^)~''☆ミ☆ミ~……

相关推荐

  1. python多线翻译获取进度结果

    2024-01-30 14:38:02       26 阅读
  2. 获取线id

    2024-01-30 14:38:02       22 阅读
  3. 并发基础之线

    2024-01-30 14:38:02       34 阅读
  4. C++多线并发

    2024-01-30 14:38:02       20 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-30 14:38:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-30 14:38:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-01-30 14:38:02       87 阅读
  4. Python语言-面向对象

    2024-01-30 14:38:02       96 阅读

热门阅读

  1. k8s默认seccomp禁用研究

    2024-01-30 14:38:02       63 阅读
  2. 【算法】传纸条(动态规划)

    2024-01-30 14:38:02       59 阅读
  3. oracle分区范围修改与数据迁移处理

    2024-01-30 14:38:02       58 阅读
  4. 数据结构-排序

    2024-01-30 14:38:02       71 阅读
  5. 消息队列和Kafka

    2024-01-30 14:38:02       48 阅读
  6. Spring 注解详情

    2024-01-30 14:38:02       69 阅读
  7. 学fpga和还是嵌入式?

    2024-01-30 14:38:02       58 阅读
  8. Chrome 121 释出

    2024-01-30 14:38:02       65 阅读