最近在写一些powershell脚本时候遇到一个问题,那就是要解压十几个zip文件,这样仅执行完解压操作差不多5min的时间就过去了,严重影响了效率,这时就想到了使用多线程的方法来执行这个解压操作,经过学习了解到powershell提供了一个Start-Job命令来实现并行执行。接下来对这个命令做一个总结。


一、真实案例

  以我之前遇到的问题作为示例来介绍这个命令,先贴出源方案,串行执行。c:\zipfile目录下有十几个zip文件,需要对文件进行解压,按照原有的方案是遍历整个目录,一次解压,耗时5min。

foreach ( $i in ls c:\zipfile\*.zip)
{
.\7z.exe x $i
}

  利用start-job后的代码:

foreach ( $i in ls c:\zipfile\*.zip)
{
$command = ".\7z.exe x $i"
Start-Job -ScriptBlock{ $command }     #注意:在{}中不可以传入“.\7z.exe x $i”类似这样命令与变量的结合体,{}接收的是类似$command这样的字符串或者是“.\7z.exe x a.zip”这样的内容。否则会报错哦
}

  使用并行执行的方案后,执行时长缩小到了1min。

二、熟练使用start-job及相关配套命令

  1、start-job  

    后台运行sleep命令,并且为这个任务命名为“sleep”。  

Start-Job -ScriptBlock { sleep 10 } -Name sleep

    在后台运行命令前首先将1赋值给$a,然后再去执行输出$a的操作,最后命名为test,-InitializationScript参数的作用是任务开始前需要执行的。

Start-Job -InitializationScript { $a = 1 } -ScriptBlock { echo $a } -Name test

    若需要后台执行脚本,使用-FilePath参数即可

Start-Job -FilePath .\a.ps1

  2、get-job

  获取当前所有后台进程的状态信息,starte是任务的执行状态,“Completed”表示任务完成,“Failed”表示任务执行失败,“Running”表示正在运行的,“Stopped”表示任务停止。

PS C:\> Get-Job

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
-- ---- ------------- ----- ----------- -------- -------
29 Job29 BackgroundJob Completed True localhost mkdir c:\a\b...
31 test1 BackgroundJob Failed False localhost slepp 20

  3、stop-job

  停止后台运行的某个任务,下面的例子是后台运行一个睡20s的任务,得知该任务的id是43,然后停止id=43的任务,再去查看后台任务。如果知道后台任务的名称,也可以根据名字来停止(参数是-Name)

PS C:\Users\bill> Start-Job -ScriptBlock{ sleep 20}

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
-- ---- ------------- ----- ----------- -------- -------
43 Job43 BackgroundJob Running True localhost sleep 20 PS C:\Users\bill> Stop-Job -id 43 PS C:\Users\bill> Get-Job Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
43 Job43 BackgroundJob Stopped False localhost sleep 20

  4、receive-job

   我们在使用start-job后台执行任务的时候,往往是不会显示命令的执行结果,此时可以使用receive-job命令查看它的结果

PS C:\Users\bill> Start-Job -ScriptBlock { echo "1" } -Name "ok"

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
-- ---- ------------- ----- ----------- -------- -------
45 ok BackgroundJob Running True localhost echo "1" PS C:\Users\bill> Receive-Job -Name ok
1

  5、wait-job

  再回到最初的案例,对文件解压完后,需要将各个解压文件移动到某个位置,但是使用start-job将每个解压任务放到后台,此时系统会接着执行后续的操作,这时出现了文件还没有解压完成,就已经开始对解压文件进行操作,导致脚本异常。针对这个问题需要用到wait-job命令。

PS C:\> Start-Job -ScriptBlock { sleep 5 } -Name s1
Start-Job -ScriptBlock { sleep 6 } -Name s2
Start-Job -ScriptBlock { sleep 7 } -Name s3
echo "satrt" Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
47 s1 BackgroundJob Running True localhost sleep 5
49 s2 BackgroundJob Running True localhost sleep 6
51 s3 BackgroundJob Running True localhost sleep 7
satrt

  我们可以看到三个后台任务和输出“start”几乎是同时执行的,加入wait-job后

PS C:\> Start-Job -ScriptBlock { sleep 5 } -Name s1
Start-Job -ScriptBlock { sleep 6 } -Name s2
Start-Job -ScriptBlock { sleep 7 } -Name s3
Wait-Job *
echo "satrt" Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
53 s1 BackgroundJob Running True localhost sleep 5
55 s2 BackgroundJob Running True localhost sleep 6
57 s3 BackgroundJob Running True localhost sleep 7
57 s3 BackgroundJob Completed False localhost sleep 7
55 s2 BackgroundJob Completed False localhost sleep 6
53 s1 BackgroundJob Completed False localhost sleep 5
satrt

  加入wait-job命令后的现象是,等待所有的后台命令执行完成后,才去执行echo “start”。此时就明白了wait-job的作用了,那就是等待执行的任务完成后再去执行其他的。

  其中wait-job中-Id和-Name可以指定特定的任务。

  若不用wait-job命令可以下面的代码来监控后台任务是否执行完

Remove-Job *
#测试计时开始
$start_time = (Get-Date) Start-Job -ScriptBlock { sleep 9; Write-Host "Hello myJob1."; } -Name "myJob1"
Start-Job -ScriptBlock { sleep 5; Write-Host "Hello myJob2."; } -Name "myJob2"
$taskCount = 2
while($taskCount -gt 0)
{
foreach($job in Get-Job)
{
$state = [string]$job.State
if($state -eq "Completed")
{
Write-Host($job.Name + " 已经完成")
Receive-Job $job
$taskCount--
Remove-Job $job
}
}
sleep 1
}
"所有任务已完成" #得出任务运行的时间
(New-TimeSpan $start_time).totalseconds

  以上的作用是等待所有后台任务结束后才会执行后续的操作,还有一种参数是-Any,它的作用是等待后台任务中任意一个介绍就会执行后续操作。

Remove-Job *

Start-Job -ScriptBlock{ sleep 2 } -Name a1
Start-Job -ScriptBlock { sleep 30} -Name a2
Wait-Job -Any *

  等上述执行完成后,查看get-job,可以看到“sleep 30”还在进行。即有一个后台任务结束后就不在等待!

PS C:\Windows\system32> Get-Job

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
-- ---- ------------- ----- ----------- -------- -------
115 a1 BackgroundJob Completed False localhost sleep 2
117 a2 BackgroundJob Running True localhost sleep 30

 6、remove-job

  删除后台运行的任务,前提条件是该后台任务是停止状态

PS C:\> Get-Job

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
-- ---- ------------- ----- ----------- -------- -------
53 s1 BackgroundJob Completed False localhost sleep 5
55 s2 BackgroundJob Completed False localhost sleep 6
57 s3 BackgroundJob Completed False localhost sleep 7
59 rm BackgroundJob Completed False localhost sleep 20 PS C:\> Remove-Job -Name rm PS C:\> Get-Job Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
53 s1 BackgroundJob Completed False localhost sleep 5
55 s2 BackgroundJob Completed False localhost sleep 6
57 s3 BackgroundJob Completed False localhost sleep 7 PS C:\> Remove-Job * PS C:\> Get-Job

 三、start-job传入参数

   将参数传入start-job需要用到两个,一个是花括号中的param(),另一个是ArguementList,具体实例如下。

PS C:\> $a = "name"

PS C:\> $b = "bill"

PS C:\> Start-Job -ScriptBlock{ param($a,$b) echo "$a == $b" }  -ArgumentList $a,$b

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
-- ---- ------------- ----- ----------- -------- -------
67 Job67 BackgroundJob Running True localhost param($a,$b) echo "$a... PS C:\> Receive-Job -id 67
name == bill

  over!

  

 

并行执行任务 Stat-Job的更多相关文章

  1. 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel)

    Task - 基于线程池的任务(在 System.Threading.Tasks 命名空间下) 多 Task 的并行执行 Parallel - 并行计算(在 System.Threading.Task ...

  2. Java使用Fork/Join框架来并行执行任务

    现代的计算机已经向多CPU方向发展,即使是普通的PC,甚至现在的智能手机.多核处理器已被广泛应用.在未来,处理器的核心数将会发展的越来越多. 虽然硬件上的多核CPU已经十分成熟,但是很多应用程序并未这 ...

  3. 深入解析SQL Server并行执行原理及实践(上)

    在成熟领先的企业级数据库系统中,并行查询可以说是一大利器,在某些场景下他可以显著的提升查询的相应时间,提升用户体验.如SQL Server, Oracle等, Mysql目前还未实现,而Postgre ...

  4. 深入解析SQL Server并行执行原理及实践(下)

    谈完并行执行的原理,咱们再来谈谈优化,到底并行执行能给我们带来哪些好处,我们又应该注意什么呢,下面展开. Amdahl’s  Law 再谈并行优化前我想有必要谈谈阿姆达尔定律,可惜老爷子去年已经驾鹤先 ...

  5. Oracle并行执行特性应用初探

    1.      序 在历史数据转出测试过程中,通过不断的优化,包括SQL调整和数据库调整,从AWR中看到,基本上难以进行更多的性能提升,于是准备试试并行执行的特性,从这个任务的特点来分析,也比较适合采 ...

  6. 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel)

    [源码下载] 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel) 作者:webabcd 介绍重新想象 W ...

  7. 并行执行的Service,以媒体转码成新格式为例

    大家众所周知,IntentService内置的handler只有一个线程,而AsyncTask又只适合时间至多几秒的操作,所以我们关注使用ExecutorService建立并行执行.为了确保Servi ...

  8. Java中使用ThreadPoolExecutor并行执行独立的单线程任务

    Java SE 5.0中引入了任务执行框架,这是简化多线程程序设计开发的一大进步.使用这个框架可以方便地管理任务:管理任务的生命周期以及执行策略. 在这篇文章中,我们通过一个简单的例子来展现这个框架所 ...

  9. Selenium WebDriver + Grid2 + RSpec之旅(六) ----多浏览器的并行执行

    Selenium WebDriver + Grid2 + RSpec之旅(六) ----多浏览器的并行执行 由于浏览器的发展,浏览器种类繁多.为了保证系统能在各种浏览器上叱咤风云,减少测试人员的测试工 ...

  10. Jenkins 在声明式 pipeline 中并行执行任务

    在持续集成的过程中,并行的执行那些没有依赖关系的任务可以缩短整个执行过程.Jenkins 的 pipeline 功能支持我们用代码来配置持续集成的过程.本文将介绍在 Jenkins 中使用声明式 pi ...

随机推荐

  1. Java7与Java8中的HashMap和ConcurrentHashMap知识点总结

    JAVA7 Java7的ConcurrentHashMap里有多把锁,每一把锁用于其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率呢.这 ...

  2. python通过一句话判断闰年的代码

    [str(i)+'闰年' for i in range(2000,2100) if i%4 ==0 and i%100 !=0]

  3. Nginx+keepalived 高可用双机热备(主从模式)

    环境:centos7.6 最小化安装 主:10.11.1.32 从:10.11.1.33 VIP:10.11.1.130 修改主节点主机名: hostnamectl set-hostname web_ ...

  4. volatile原理

    内存可见性 内存可见性相关概念:线程对共享变量修改的可见性.当一个线程修改了共享变量的值,其他线程能够立刻得知这个修改. 后面会继续总结一篇<Java内存模型(JMM)总结>以详细描述内存 ...

  5. Cocos2d-x学习小结 开始篇

    Cocos2d-x学习小结 开始篇 想要学习Cocos2d-x,是因为在高中物理课上找不到某些物理定律的证明,例如欧姆定律. 为此,我翻阅了稍高等级的物理教材,其中关于欧姆定律\(R=\frac{U} ...

  6. Xamarin开发及学习资源

    入行文章指引 移动开发下Xamarin VS PhoneGap 跨平台开发 许多企业希望能够通过开发移动应用程序,来提升企业业务水平,开发原生App时往往又缺少专业的Objective C 或 Jav ...

  7. pgloader 学习(三)快速使用

    pgloader 支持多种数据源数据的加载,以下列出简单的操作命令,后边会有详细的使用说明 csv 格式内容加载 预备说明 需要先在pg 数据库创建表 create table districts_l ...

  8. 01-复杂度2 Maximum Subsequence Sum (25 分)

    Given a sequence of K integers { N​1​​, N​2​​, ..., N​K​​ }. A continuous subsequence is defined to ...

  9. Tkinter 之文件管理器

    一.效果图 二.功能描述 1.打开文件菜单中的打开按钮,可以选择目录. 2.可以查看各种类型的图片. 3.可以编辑文本. 4.显示行号功能,可改变目录显示的宽度. 三.使用的标签 1.Menu 2.F ...

  10. Koa 脚手架创建项目

    Koa 脚手架创建项目 通过应用 koa 脚手架生成工具 可以快速创建一个基于 koa2 的应用的骨架 全局安装koa npm install koa-generator -g //必须安装到全局 创 ...