Powershell 将变量传递给流的实验

Powershell 将变量传递给流的实验,powershell,runspace,Powershell,Runspace,我想了解流是如何相互通信的。更准确地说,当一个新线程诞生并向其传递一个变量时,这就是一个公共变量或同步副本 下面是我要做的事情: $A = '0' # Expansion of the variable to 32 MB (2^25 characters) (1..25).ForEach{ $A += $A -join '' } $A $A.Length # Torment further. Writing a variable to a table $B = [HashTable]::S

我想了解流是如何相互通信的。更准确地说,当一个新线程诞生并向其传递一个变量时,这就是一个公共变量或同步副本

下面是我要做的事情:

$A = '0'

# Expansion of the variable to 32 MB (2^25 characters)
(1..25).ForEach{ $A += $A -join '' }

$A
$A.Length

# Torment further. Writing a variable to a table
$B = [HashTable]::Synchronized(@{ Name = $A })

Clear-Variable A
Remove-Variable A

$B

Write-host "Oh, that wasn't easy. Owner, maybe enough?"

# But no, not enough. Now you pass B to another thread

$RunSpace = [Runspacefactory]::CreateRunspace()
$RunSpace.Open()
$RunSpace.SessionStateProxy.SetVariable('B', $B )
$PowerShell = [PowerShell]::Create().AddScript({})
$PowerShell.Runspace = $RunSpace

$Null = $PowerShell.BeginInvoke()

# Here I do not close the threads for clarity
这是我在内存图上看到的:

我意识到我使用的是$B哈希表的同步副本,而不是一个表。但是如果有很多这样大的表和很多线程呢?我是不是彻底浪费了记忆

我真的被迫为每个线程创建相同$B哈希表的副本吗?我不能为所有线程创建一个通用的$B哈希表吗?

编辑。我决定提高赌注,将
1..30
改为
1..25
(2乘以30的幂,即$A)≡ 1GB(!!!))。我看到了什么?第一步和第二步增加了1GB。也就是说,另一个1GB表被传输到流中。结果,我得到了2GB

看看这个:


我认为这只是创建了该变量的一个副本:

$RunSpace.SessionStateProxy.SetVariable('B',$B)

您需要将其作为参数传递。下面是一个例子

$LargeVar = [System.IO.File]::ReadAllBytes("C:\temp\SomeLargeFile.zip")

$work = { param($SharedVar)

   $threadId = [System.AppDomain]::GetCurrentThreadId()
   Write-Output "Thread $threadId : result $($SharedVar.count)"    
}

$workParams = @{SharedVar = $LargeVar}

$rs1 = [powershell]::Create()
$rs2 = [powershell]::Create()
$rs3 = [powershell]::Create()

foreach($rs in $rs1, $rs2, $rs3) {

   $rs.AddScript($work).AddParameters($workParams).Invoke()
   $rs.Commands.Clear() 

}

如果要并行调用运行空间,可能需要创建并发集合并使用它在运行空间之间交换数据

运行空间共享内存,因此可以将相同的变量从主线程传递到运行空间。线程本身使用大约2MB的内存,这可能是你在第二次碰撞中看到的。我想相信它。然而,@Mike Twc请查看编辑后的帖子。我将变量的大小增加到1GB,总共得到2GB($A加$B)。如果哈希表是共享的(大小为1GB),这怎么可能呢?谢谢。如果我更改子流中的哈希表呢?据我所知(如果作为参数传递),我无法获得父线程中的更改。