我正在尝试在Powershell Core中运行一些脚本(没有工作流程,没有ForEach的-Parallel选项)。
因此,我尝试将数组拆分为多个数组并并行运行。所以我这样做:
$iterCount = 150000;
$threadCount = 8;
$batchSize = $iterCount/$threadCount;
$block = {
Param($range)
Foreach ($i in $range) {
...
}
}
For ($i = 0; $i -lt 150000; $i += $batchSize) {
Start-Job -Scriptblock $block -ArgumentList $i..$i+$batchSize
}
但是当我叫它
Start-Job : Cannot bind parameter 'InitializationScript'. Cannot convert the ".. 0+18750" value of type "System.String" to type "System.Management.Automation.Scr iptBlock".
At /home/tchain/dit/push_messages3.ps1:63 char:48
+ Start-Job -Scriptblock $block -ArgumentList $i..$i+$batchSize
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Start-Job], ParameterBindingExce ption
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Co mmands.StartJobCommand
似乎ArgumentList
对所有内容都进行了字符串化处理,所以我无法通过范围。
有没有办法传递强类型范围?有没有更好的并行循环方法?我想写(0..150000).AsParallel().ForEach($i => ...)
,但看来我不会。
我做了Param([int] $from, [int] $to)
的一种解决方法,但是我不确定这是否是我能做到的最好的方法。
答案 0 :(得分:1)
使用临时变量来创建所需大小的数组,而不是在参数列表中评估范围运算符。然后将数组作为参数传递。像这样
For ($i = 0; $i -lt 150000; $i += $batchSize) {
$j = $i+$batchSize
$range = $i..$j
Start-Job -Scriptblock $block -ArgumentList (,$range)
}
编辑:-ArgumentList
解散该数组,因此需要a bit trickery。
通过打印有关传递的数组的详细信息来测试代码:
$block = {
Param([array]$range)
write-host "len`t[0]`t[-1]"
write-host $range.length"`t"$range[0]"`t"$range[-1]
}
For ($i = 0; $i -lt 150000; $i += $batchSize) {
$j = $i+$batchSize
$range = $i..$j
Start-Job -Scriptblock $block -ArgumentList (,$range)
}
get-job | receive-job
len [0] [-1]
18751 0 18750
len [0] [-1]
18751 18750 37500
len [0] [-1]
18751 37500 56250
len [0] [-1]
18751 56250 75000
len [0] [-1]
18751 75000 93750
len [0] [-1]
18751 93750 112500
len [0] [-1]
18751 112500 131250
len [0] [-1]
18751 131250 150000
答案 1 :(得分:0)
范围运算符“ ..”从字面上创建具有多个整数的数组。就像“” $ array + = element“一样,” 1 .. $ highnumber“会占用大量内存。for循环在工作中应该可以正常工作。您也永远不要使用$ iterCount。
还请注意,作业使用新流程。但是您可以在PS 6中使用start-threadjob代替线程。
#$iterCount = 150000;
$iterCount = 24
$threadCount = 8;
$batchSize = $iterCount/$threadCount;
$block = {
Param($start,$range)
"start $start range $range"
For ($i = $start; $i -lt $range; $i++) {
$i
}
}
For ($i = 0; $i -lt $iterCount; $i += $batchSize) {
Start-Job -Scriptblock $block -ArgumentList $i,($i+$batchSize)
}
start 0 range 3
0
1
2
start 3 range 6
3
4
5
start 6 range 9
6
7
8
start 9 range 12
9
10
11
start 12 range 15
12
13
14
start 15 range 18
15
16
17
start 18 range 21
18
19
20
start 21 range 24
21
22
23
出于比较目的,实际上在脚本块中创建了范围“ ..”。接收作业的输出可能显示为乱序。
$iterCount = 150000
$threadCount = 8
$batchSize = $iterCount/$threadCount
$block = {
Param($start,$range)
"start $start range $range"
Foreach ($i in $start..($range-1)) {
# $i
}
}
For ($i = 0; $i -lt $iterCount; $i += $batchSize) {
Start-Job -Scriptblock $block -ArgumentList $i,($i+$batchSize)
}
start 0 range 18750
start 18750 range 37500
start 75000 range 93750
start 131250 range 150000
start 93750 range 112500
start 37500 range 56250
start 56250 range 75000
start 112500 range 131250