最近在写一些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. MySQL的增、删、改、查

    数据库的常用命令以及作用 用法 作用 CREATE database 数据库名称. 创建新的数据库 DESCRIBE 表单名称; 描述表单 UPDATE 表单名称 SET attribute=新值 W ...

  2. phantomJS+Python 隐形浏览器

    phantomjs解压后,把文件夹bin中的phantomjs.exe移到python文件夹中的Scripts中 实例: from selenium import webdriver driver = ...

  3. Echo团队Alpha冲刺随笔 - 第十天

    项目冲刺情况 进展 对Web端和小程序端进行各项功能的测试 问题 bug无穷无尽 心得 debug使人秃头,希望明天能挑好 今日会议内容 黄少勇 今日进展 测试小程序,对发现的bug进行处理 存在问题 ...

  4. Alpha冲刺(9/10)——2019.5.2

    所属课程 软件工程1916|W(福州大学) 作业要求 Alpha冲刺(9/10)--2019.5.2 团队名称 待就业六人组 1.团队信息 团队名称:待就业六人组 团队描述:同舟共济扬帆起,乘风破浪万 ...

  5. GlusterFS集群文件系统研究

    https://blog.csdn.net/liuaigui/article/details/6284551 1.      GlusterFS概述GlusterFS是Scale-Out存储解决方案G ...

  6. Idea中,项目文件右键菜单没有svn选项处理办法

    问题描述 IntelliJ IDEA打开带SVN信息的项目,在项目文件上点击右键,菜单中没有Subversion的功能项,如下图: 解决办法 点击菜单:VCS -> Enabled Versio ...

  7. selenium原理解析

    相信很多测试小伙伴儿都听过或者使用过web自动化selenium,那您有没有研究过selenium的原理呢?为什么要使用webdriver.exe,webdriver.exe是干啥用的?seleniu ...

  8. Hibernate对象持久化的三种状态

    1.三种状态: public static void testSel() { Session session = HibernateUtils.openSession(); Transaction t ...

  9. P2624 [HNOI2008]明明的烦恼

    #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #inclu ...

  10. 干货 | column generation求解VRPTW问题 java代码分享

    00 前言 经过小编不断的努力,关于column generation求解VRPTW的代码终于新鲜出炉啦. 01 运行说明 关于这部分的代码,这里提供两个版本. 第一个版本GitHub一个叫Semin ...