[玩转系统] 多线程时显示进度
作者:精品下载站 日期:2024-12-14 03:03:48 浏览:15 分类:玩电脑
多线程时显示进度
从 PowerShell 7.0 开始,使用 Foreach-Object cmdlet 中的 Parallel 参数可以同时在多个线程中工作。不过,监控这些线程的进度可能是一个挑战。通常,您可以使用 Write-Progress 监视进程的进度。但是,由于 PowerShell 在使用并行时为每个线程使用单独的运行空间,因此向主机报告进度并不像正常使用Write-Progress
那样直接。
使用同步哈希表来跟踪进度
当从多个线程写入进度时,跟踪变得很困难,因为在 PowerShell 中运行并行进程时,每个进程都有自己的运行空间。为了解决这个问题,您可以使用同步哈希表。同步哈希表是一种线程安全的数据结构,可以由多个线程同时修改而不会引发错误。
设置
这种方法的缺点之一是它需要稍微复杂的设置才能确保一切运行没有错误。
$dataset = @(
@{
Id = 1
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 2
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 3
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 4
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 5
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
)
# Create a hashtable for process.
# Keys should be ID's of the processes
$origin = @{}
$dataset | Foreach-Object {$origin.($_.id) = @{}}
# Create synced hashtable
$sync = [System.Collections.Hashtable]::Synchronized($origin)
本节出于三个不同的目的创建了三种不同的数据结构。
$dataSet
变量存储一个哈希表数组,用于协调后续步骤,而不会产生被修改的风险。如果在迭代对象集合时修改该集合,PowerShell 将引发错误。您必须将循环中的对象集合与正在修改的对象分开。每个哈希表中的 Id
键是模拟进程的标识符。 Wait
键模拟被跟踪的每个模拟进程的工作负载。
$origin
变量存储一个嵌套哈希表,每个键都是模拟进程 ID 之一。然后,它用于合并存储在 $sync
变量中的同步哈希表。 $sync
变量负责将进度报告回父运行空间,后者显示进度。
运行进程
此部分运行多线程进程并创建一些用于显示进度的输出。
$job = $dataset | Foreach-Object -ThrottleLimit 3 -AsJob -Parallel {
$syncCopy = $using:sync
$process = $syncCopy.$($PSItem.Id)
$process.Id = $PSItem.Id
$process.Activity = "Id $($PSItem.Id) starting"
$process.Status = "Processing"
# Fake workload start up that takes x amount of time to complete
start-sleep -Milliseconds ($PSItem.wait*5)
# Process. update activity
$process.Activity = "Id $($PSItem.id) processing"
foreach ($percent in 1..100)
{
# Update process on status
$process.Status = "Handling $percent/100"
$process.PercentComplete = (($percent / 100) * 100)
# Fake workload that takes x amount of time to complete
Start-Sleep -Milliseconds $PSItem.Wait
}
# Mark process as completed
$process.Completed = $true
}
模拟进程被发送到 Foreach-Object 并作为作业启动。 ThrottleLimit 设置为 3 以突出显示队列中正在运行的多个进程。这些作业存储在 $job
变量中,使我们能够知道所有进程稍后何时完成。
在 PowerShell 中使用 using:
语句引用父作用域变量时,不能使用表达式使其动态化。例如,如果您尝试创建像这样的 $process
变量,$process=$using:sync.$ ($PSItem.id)
,您将得到错误表明您不能在那里使用表达式。因此,我们创建 $syncCopy
变量以便能够引用和修改 $sync
变量,而不会有失败的风险。
接下来,我们通过引用同步哈希表键,使用 $process
变量构建一个哈希表来表示当前循环中进程的进度。 Activity 和 Status 键用作 Write-Progress
的参数值,以在下一部分中显示给定模拟进程的状态。
foreach
循环只是模拟流程工作的一种方式,并根据 $dataSet
Wait 属性随机设置 Start-使用毫秒休眠。您计算流程进度的方式可能会有所不同。
显示多个进程的进度
现在模拟进程已作为作业运行,我们可以开始将进程进度写入 PowerShell 窗口。
while($job.State -eq 'Running')
{
$sync.Keys | Foreach-Object {
# If key is not defined, ignore
if(![string]::IsNullOrEmpty($sync.$_.keys))
{
# Create parameter hashtable to splat
$param = $sync.$_
# Execute Write-Progress
Write-Progress @param
}
}
# Wait to refresh to not overload gui
Start-Sleep -Seconds 0.1
}
$job
变量包含每个模拟进程的父 job 和子 job。当任何子作业仍在运行时,父作业状态将保持“正在运行”。这允许我们使用 while 循环不断更新每个进程的进度,直到所有进程完成。
在 while 循环中,我们循环遍历 $sync 变量中的每个键。由于这是一个同步哈希表,因此它会不断更新,但仍然可以访问而不会引发任何错误。
使用 IsNullOrEmpty()
方法进行检查以确保所报告的进程实际上正在运行。如果该进程尚未启动,则循环将不会报告该进程并继续执行下一个进程,直到到达已启动的进程。如果进程启动,则使用当前键的哈希表将参数分配给 Write-Progress
。
完整示例
# Example workload
$dataset = @(
@{
Id = 1
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 2
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 3
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 4
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 5
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
)
# Create a hashtable for process.
# Keys should be ID's of the processes
$origin = @{}
$dataset | Foreach-Object {$origin.($_.id) = @{}}
# Create synced hashtable
$sync = [System.Collections.Hashtable]::Synchronized($origin)
$job = $dataset | Foreach-Object -ThrottleLimit 3 -AsJob -Parallel {
$syncCopy = $using:sync
$process = $syncCopy.$($PSItem.Id)
$process.Id = $PSItem.Id
$process.Activity = "Id $($PSItem.Id) starting"
$process.Status = "Processing"
# Fake workload start up that takes x amount of time to complete
start-sleep -Milliseconds ($PSItem.wait*5)
# Process. update activity
$process.Activity = "Id $($PSItem.id) processing"
foreach ($percent in 1..100)
{
# Update process on status
$process.Status = "Handling $percent/100"
$process.PercentComplete = (($percent / 100) * 100)
# Fake workload that takes x amount of time to complete
Start-Sleep -Milliseconds $PSItem.Wait
}
# Mark process as completed
$process.Completed = $true
}
while($job.State -eq 'Running')
{
$sync.Keys | Foreach-Object {
# If key is not defined, ignore
if(![string]::IsNullOrEmpty($sync.$_.keys))
{
# Create parameter hashtable to splat
$param = $sync.$_
# Execute Write-Progress
Write-Progress @param
}
}
# Wait to refresh to not overload gui
Start-Sleep -Seconds 0.1
}
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag