2012-02-03 155 views
0

我有8个PowerShell脚本。很少有人有依赖性。这意味着它们不能并行执行。他们应该被陆续执行。并行化powershell脚本执行

一些Powershell脚本没有依赖性,可以并行执行。

以下是依赖详细

Powershell scripts 1, 2, and 3 depend on nothing else 
    Powershell script 4 depends on Powershell script 1 
    Powershell script 5 depends on Powershell scripts 1, 2, and 3 
    Powershell script 6 depends on Powershell scripts 3 and 4 
    Powershell script 7 depends on Powershell scripts 5 and 6 
    Powershell script 8 depends on Powershell script 5 

我知道,通过手动硬编码的依赖性,可以解释的。但是可能会添加10个更多的PowerShell脚本,并且可能会添加它们之间的依赖关系。

有没有找到依赖关系的并行?如果是这样,请与我分享如何继续。

回答

1

你对一般的并行编程有多熟悉?您是否听说过使用mutual exclusion的概念?通常的概念是使用某种消息/锁定机制来保护不同并行线程之间的共享资源。

就你而言,你将分隔线本身作为脚本 - 我认为这可能比这篇维基百科文章中概述的大多数技术简单得多。这个简单的模板是否适用于您要查找的内容?

  1. 在本地文件系统中定义一个文件夹。这个位置将被所有脚本知道(默认参数)。
  2. 在运行任何脚本之前,请确保删除该目录中的任何文件。
  3. 对于每个脚本,作为它们执行的最后一步,他们应该在共享目录中使用它们的脚本名称作为文件的名称编写一个文件。因此,script1.ps1会创建script1文件。
  4. 对另一个脚本有依赖性的任何脚本都将根据脚本的文件名来定义这些依赖性。如果script3依赖于script1和script2,则将在script3中将其定义为依赖项参数。
  5. 所有具有依赖性的脚本都将运行一个函数,该函数检查文件是否存在于它所依赖的脚本中。如果是,则继续执行脚本,否则会暂停,直到完成为止。
  6. 所有脚本通过主脚本/批处理文件同时启动。所有脚本都作为PowerShell作业运行,以便操作系统将并行运行它们的执行。大多数脚本会启动,看到它们有依赖关系,然后耐心等待这些问题得到解决,然后再继续执行脚本主体。

好消息是,这将允许灵活地改变依赖关系。每个脚本都会写一个文件,不要假设别人是否在等待它。改变特定脚本的依赖关系将是一个简单的单行更改或输入参数的更改。

虽然这绝对不是一个完美的解决方案。例如,如果一个脚本失败会发生什么(或者你的脚本可以在多个不同的代码路径中退出,但你忘记在其中的一个中写入文件)?这可能会导致死锁情况,其中不会有依赖脚本被启动。另一件坏事是在等待正确的文件被创建时忙着等待睡眠或旋转 - 这可以通过执行Event-based方法来纠正,您可以通过该方法让操作系统监视目录以进行更改。

希望这有助于并不是所有的垃圾。

+0

这不仅仅是一个答案,你让我思考并行性太严重。感谢您的杰出答案。 – Samselvaprabu 2012-02-04 03:18:40

1

你只需要适当地给你打电话。没有内置的东西可以处理你的依赖关系。

同时运行1,2,3,Start-Job

他们

等待的同时Start-Job

等待它们得到完成Get-Job -State Running | Wait-Job

运行6,等待它得到完成Get-Job -State Running | Wait-Job

运行4,5。同时Start-Job

+0

您提到的方式就像通过硬编码一样。可能会添加更多的脚本文件,并且依赖关系也会改变。一些算法可能会有好处。 – Samselvaprabu 2012-02-03 06:29:48

5

你需要看的PowerShell 3.0工作流程

运行7,8。它提供了您需要的功能。类似这样的:

workflow Install-myApp { 
    param ([string[]]$computername) 
    foreach -parallel($computer in $computername) { 
     "Installing MyApp on $computer" 
     #Code for invoking installer here 
     #This can take as long as 30mins and may reboot a couple of times 
    } 
} 

workflow Install-MyApp2{ 
    param ([string[]]$computername) 
    foreach -parallel($computer in $computername) { 
     "Installing MyApp2 on $computer" 
     #Code for invoking installer here 
     #This can take as long as 30mins! 
    } 
} 

WorkFlow New-SPFarm { 
    Sequence { 
     Parallel { 
      Install-MyApp2 -computername "Server2","Server3" 
      Install-MyApp -computername "Server1","Server4","Server5" 
     } 
     Sequence { 
      #This activity can happen only after the set of activities in the above parallel block are complete" 
      "Configuring First Server in the Farm [Server1]" 

      #The following foreach should take place only after the above activity is complete and that is why we have it in a sequence 
      foreach -parallel($computer in $computername) { 
       "Configuring SharePoint on $computer" 
      } 
     } 
    } 
} 
+0

伟大的提示。我认为它会实现一些算法的一点点补充。 – Samselvaprabu 2012-02-03 08:12:38

+1

良好的工作流程:-)当它变得广泛可用时,这将是一个不错的功能。 OP仍然需要手动布置并行和顺序分组的顺序,与后台作业所需的顺序相同。我认为他正在寻找如何使用SCM来管理启动顺序的Windows服务依赖关系的工作 – 2012-02-03 08:12:42

+0

实际上,您可以使用适当的顺序和并行活动顺序来实现。我并没有真正想看看他正在寻找的确切顺序。但是,这个通用模板应该是一个很好的起点。 – ravikanth 2012-02-03 09:06:34