ps第19课:不用多线程,你对不起powershell
-------1【多线程powershell脚本,使用场景】---------
多线程只能解决2种问题,一cpu密集型问题,二io密集型问题。
对于cpu密集型问题,一般4核心cpu,一般用3---5线程。8核心cpu,用7---9线程即可。
对于io密集型问题,可以线程数可以是cpu的n倍。比如4核心cpu,可以用40-400线程。具体倍数自己测试着来。
此贴告诉你:为啥shell脚本人,不建议学python
在这篇帖子中,我总结了python的十多个癌症。
其中有一个著名的癌症,就是【python多线程只能用1个核心】,
而基于.net,.net core的powershell没有这个问题,多线程可以用多个核心。
py可以用单线程+asyncio解决部分io密集型问题。但是cpu密集型问题,就是powershell的菜了。
-------2【powershell多线程代码模型】---------
多线程模型,建议用:
1powershell v5 + rsjob模块,PoshRSJob
它的用法类似于powershell的start-job,但是start-job是使用了进程隔离。而它使用了powershell runspace多线程。
2powershell v7自带的ForEach-Object -Parallel。这个也是基于powershell runspace多线程。
┏┳━━━━━━━━━━━┓
┃┃███████████┃
┃┃███████████┃
┣┫███████┏━┓█┃
┃┃███████┃P┃█┃
┃┃███████┃O┃█┃
┃┃███秘███┃W┃█┃
┣┫███████┃E┃█┃
┃┃███████┃R┃█┃
┃┃███████┃S┃█┃
┃┃███████┃H┃█┃
┣┫███████┃E┃█┃
┃┃███籍███┃L┃█┃
┃┃███████┃L┃█┃
┃┃███████┗━┛█┃
┣┫███████████┃
┃┃██V7.0 preview3 ██┃
┃┃███████████┃
┗┻━━━━━━━━━━━┛
新增并发参数
| ForEach-Object -Parallel例子:
1
get-content ip.txt |foreach-object -Parallel{ ping.exe $_ }
2
Get-Content /powershell/ip.txt |ForEach-Object -Parallel {if (Test-Connection -Count 1 -TargetName $_ -Quiet) {$_} } 6>$null
3
$a = 1..100
$a | ForEach-Object -ThrottleLimit 5 -Parallel {
Write-Host $_
Start-Sleep -Seconds 3
}
手册:
github上的com/PowerShell/PowerShell-RFC/blob/master/4-Experimental-Accepted/RFC0044-ForEach-Parallel-Cmdlet.md
参数:
-Parallel
-ThrottleLimit
-TimeoutSeconds parameter takes an integer that specifies the maximum time to wait for completion before the command is aborted
-AsJob
-------3【多线程变量】---------
-------3-1【多线程变量(线程安全型变量)之,并发哈希表】---------
脚本示例:
$并发哈希表_线程安全型 = New-Object System.Collections.Concurrent.ConcurrentDictionary [string,int]
$并发哈希表_线程安全型 = New-Object "System.Collections.Concurrent.ConcurrentDictionary [string,int]"
$并发哈希表_线程安全型.TryAdd('a',1) #线程1
$并发哈希表_线程安全型
$并发哈希表_线程安全型.TryUpdate('a',2,1) #线程2
$并发哈希表_线程安全型
手册:
巨硬家.microsoft.com/zh-cn/dotnet/api/system.collections.concurrent.concurrentdictionary-2?view=netframework-4.8
-------3-2【多线程变量(线程安全型变量)之,并发数组(元素可重复的无序集合)ConcurrentBag】---------
问:去哪学win,linux通用的powershell?
答:
QQ群号=183173532
名称=powershell交流社区
公司:可以收取少许费用,群内远程帮你公司代培训员工。
个人:免费。
脚本示例:
$并发数组_线程安全型 = New-Object 'System.Collections.Concurrent.ConcurrentBag[object]'
$并发数组_线程安全型.add((get-date))
start-sleep -second 1
$并发数组_线程安全型.add((get-date))
$并发数组_线程安全型
start-sleep -second 5
$a = $null
$并发数组_线程安全型.TryTake([ref]$a)
$并发数组_线程安全型
$a
手册:
巨硬家.microsoft.com/zh-cn/dotnet/api/system.collections.concurrent.concurrentbag-1?view=netframework-4.8
-------3-3【多线程变量(线程安全型变量)之,并发队列(先进先出FIFO集合)ConcurrentQueue】---------
脚本示例:
$并发队列_线程安全型 = New-Object System.Collections.Concurrent.ConcurrentQueue[object]
$并发队列_线程安全型.Enqueue('a') #线程1
$并发队列_线程安全型.Enqueue('b') #线程1
$并发队列_线程安全型$xx = $null
$并发队列_线程安全型.TryDequeue([ref]$xx) #线程2
$并发队列_线程安全型
$xx
手册:
巨硬家.microsoft.com/zh-cn/dotnet/api/system.collections.concurrent.concurrentqueue-1?view=netframework-4.8--
-----3-4【多线程变量(线程安全型变量)之,并发堆栈(后进先出LIFO集合)ConcurrentStack】---------
脚本示例:
$并发堆栈_线程安全型 = New-Object System.Collections.Concurrent.ConcurrentStack[object]
$并发堆栈_线程安全型.push('a') #线程1
$并发堆栈_线程安全型.push('b') #线程1
$并发堆栈_线程安全型$xx = $null
$并发堆栈_线程安全型.Trypop([ref]$xx) #线程2
$并发堆栈_线程安全型
$xx
手册:
巨硬家.microsoft.com/zh-cn/dotnet/api/system.collections.concurrent.concurrentstack-1?view=netframework-4.8
-------3-5【多线程变量(线程安全型变量)之,满了就停产队列BlockingCollection】---------
脚本示例:
$并发_满了就阻塞队列1_线程安全型 = New-Object 'System.Collections.Concurrent.BlockingCollection [object]' 2 #队列里只能装2个猴
$并发_满了就阻塞队列1_线程安全型.tryadd('树上一只猴') #线程1
$并发_满了就阻塞队列1_线程安全型.tryadd('地上一只猴') #线程1
# powershell 传教士 2019-10-20
$并发_满了就阻塞队列1_线程安全型.tryadd('c') #线程1 添加失败
$并发_满了就阻塞队列1_线程安全型
#$并发_满了就阻塞队列1_线程安全型.add('d') #代码运行后开始添加,但是仓库已满,线程开始等待并卡住
$xx = $null
$并发_满了就阻塞队列1_线程安全型.TryTake([ref]$xx) #线程2
$xx # '树上一只猴'已经出队列
$并发_满了就阻塞队列1_线程安全型
Start-Sleep -second 5
$并发_满了就阻塞队列1_线程安全型.add('d') #线程1,队列容量为2,里面有一个'地上一只猴'。现在添加'd',则不会卡住。
$并发_满了就阻塞队列1_线程安全型 #'地上一只猴','d'
.add() #队列满了会卡住。
.tryadd() #队列满了不会卡住。添加成功返回true,队列满了添加失败会返回false。
当集合容量达到这个值得时候,向BlockingCollection添加元素的线程将会被阻塞,直到有元素被删除。
生产者/消费者模型。主要用于在限制队列长度(限制内存),的情况下,高效处理数据。
1个队列变量,2-3个线程入队,2-3个线程出队。
手册:
巨硬家.microsoft.com/zh-cn/dotnet/api/system.collections.concurrent.blockingcollection-1?view=netframework-4.8-
------4【后记】---------
一共俩猴,谢谢观看~
-------1【多线程powershell脚本,使用场景】---------
多线程只能解决2种问题,一cpu密集型问题,二io密集型问题。
对于cpu密集型问题,一般4核心cpu,一般用3---5线程。8核心cpu,用7---9线程即可。
对于io密集型问题,可以线程数可以是cpu的n倍。比如4核心cpu,可以用40-400线程。具体倍数自己测试着来。
此贴告诉你:为啥shell脚本人,不建议学python
在这篇帖子中,我总结了python的十多个癌症。
其中有一个著名的癌症,就是【python多线程只能用1个核心】,
而基于.net,.net core的powershell没有这个问题,多线程可以用多个核心。
py可以用单线程+asyncio解决部分io密集型问题。但是cpu密集型问题,就是powershell的菜了。
-------2【powershell多线程代码模型】---------
多线程模型,建议用:
1powershell v5 + rsjob模块,PoshRSJob
它的用法类似于powershell的start-job,但是start-job是使用了进程隔离。而它使用了powershell runspace多线程。
2powershell v7自带的ForEach-Object -Parallel。这个也是基于powershell runspace多线程。
┏┳━━━━━━━━━━━┓
┃┃███████████┃
┃┃███████████┃
┣┫███████┏━┓█┃
┃┃███████┃P┃█┃
┃┃███████┃O┃█┃
┃┃███秘███┃W┃█┃
┣┫███████┃E┃█┃
┃┃███████┃R┃█┃
┃┃███████┃S┃█┃
┃┃███████┃H┃█┃
┣┫███████┃E┃█┃
┃┃███籍███┃L┃█┃
┃┃███████┃L┃█┃
┃┃███████┗━┛█┃
┣┫███████████┃
┃┃██V7.0 preview3 ██┃
┃┃███████████┃
┗┻━━━━━━━━━━━┛
新增并发参数
| ForEach-Object -Parallel例子:
1
get-content ip.txt |foreach-object -Parallel{ ping.exe $_ }
2
Get-Content /powershell/ip.txt |ForEach-Object -Parallel {if (Test-Connection -Count 1 -TargetName $_ -Quiet) {$_} } 6>$null
3
$a = 1..100
$a | ForEach-Object -ThrottleLimit 5 -Parallel {
Write-Host $_
Start-Sleep -Seconds 3
}
手册:
github上的com/PowerShell/PowerShell-RFC/blob/master/4-Experimental-Accepted/RFC0044-ForEach-Parallel-Cmdlet.md
参数:
-Parallel
-ThrottleLimit
-TimeoutSeconds parameter takes an integer that specifies the maximum time to wait for completion before the command is aborted
-AsJob
-------3【多线程变量】---------
-------3-1【多线程变量(线程安全型变量)之,并发哈希表】---------
脚本示例:
$并发哈希表_线程安全型 = New-Object System.Collections.Concurrent.ConcurrentDictionary [string,int]
$并发哈希表_线程安全型 = New-Object "System.Collections.Concurrent.ConcurrentDictionary [string,int]"
$并发哈希表_线程安全型.TryAdd('a',1) #线程1
$并发哈希表_线程安全型
$并发哈希表_线程安全型.TryUpdate('a',2,1) #线程2
$并发哈希表_线程安全型
手册:
巨硬家.microsoft.com/zh-cn/dotnet/api/system.collections.concurrent.concurrentdictionary-2?view=netframework-4.8
-------3-2【多线程变量(线程安全型变量)之,并发数组(元素可重复的无序集合)ConcurrentBag】---------
问:去哪学win,linux通用的powershell?
答:
QQ群号=183173532
名称=powershell交流社区
公司:可以收取少许费用,群内远程帮你公司代培训员工。
个人:免费。
脚本示例:
$并发数组_线程安全型 = New-Object 'System.Collections.Concurrent.ConcurrentBag[object]'
$并发数组_线程安全型.add((get-date))
start-sleep -second 1
$并发数组_线程安全型.add((get-date))
$并发数组_线程安全型
start-sleep -second 5
$a = $null
$并发数组_线程安全型.TryTake([ref]$a)
$并发数组_线程安全型
$a
手册:
巨硬家.microsoft.com/zh-cn/dotnet/api/system.collections.concurrent.concurrentbag-1?view=netframework-4.8
-------3-3【多线程变量(线程安全型变量)之,并发队列(先进先出FIFO集合)ConcurrentQueue】---------
脚本示例:
$并发队列_线程安全型 = New-Object System.Collections.Concurrent.ConcurrentQueue[object]
$并发队列_线程安全型.Enqueue('a') #线程1
$并发队列_线程安全型.Enqueue('b') #线程1
$并发队列_线程安全型$xx = $null
$并发队列_线程安全型.TryDequeue([ref]$xx) #线程2
$并发队列_线程安全型
$xx
手册:
巨硬家.microsoft.com/zh-cn/dotnet/api/system.collections.concurrent.concurrentqueue-1?view=netframework-4.8--
-----3-4【多线程变量(线程安全型变量)之,并发堆栈(后进先出LIFO集合)ConcurrentStack】---------
脚本示例:
$并发堆栈_线程安全型 = New-Object System.Collections.Concurrent.ConcurrentStack[object]
$并发堆栈_线程安全型.push('a') #线程1
$并发堆栈_线程安全型.push('b') #线程1
$并发堆栈_线程安全型$xx = $null
$并发堆栈_线程安全型.Trypop([ref]$xx) #线程2
$并发堆栈_线程安全型
$xx
手册:
巨硬家.microsoft.com/zh-cn/dotnet/api/system.collections.concurrent.concurrentstack-1?view=netframework-4.8
-------3-5【多线程变量(线程安全型变量)之,满了就停产队列BlockingCollection】---------
脚本示例:
$并发_满了就阻塞队列1_线程安全型 = New-Object 'System.Collections.Concurrent.BlockingCollection [object]' 2 #队列里只能装2个猴
$并发_满了就阻塞队列1_线程安全型.tryadd('树上一只猴') #线程1
$并发_满了就阻塞队列1_线程安全型.tryadd('地上一只猴') #线程1
# powershell 传教士 2019-10-20
$并发_满了就阻塞队列1_线程安全型.tryadd('c') #线程1 添加失败
$并发_满了就阻塞队列1_线程安全型
#$并发_满了就阻塞队列1_线程安全型.add('d') #代码运行后开始添加,但是仓库已满,线程开始等待并卡住
$xx = $null
$并发_满了就阻塞队列1_线程安全型.TryTake([ref]$xx) #线程2
$xx # '树上一只猴'已经出队列
$并发_满了就阻塞队列1_线程安全型
Start-Sleep -second 5
$并发_满了就阻塞队列1_线程安全型.add('d') #线程1,队列容量为2,里面有一个'地上一只猴'。现在添加'd',则不会卡住。
$并发_满了就阻塞队列1_线程安全型 #'地上一只猴','d'
.add() #队列满了会卡住。
.tryadd() #队列满了不会卡住。添加成功返回true,队列满了添加失败会返回false。
当集合容量达到这个值得时候,向BlockingCollection添加元素的线程将会被阻塞,直到有元素被删除。
生产者/消费者模型。主要用于在限制队列长度(限制内存),的情况下,高效处理数据。
1个队列变量,2-3个线程入队,2-3个线程出队。
手册:
巨硬家.microsoft.com/zh-cn/dotnet/api/system.collections.concurrent.blockingcollection-1?view=netframework-4.8-
------4【后记】---------
一共俩猴,谢谢观看~