সমান্তরালভাবে পাওয়ারশেল কমান্ডগুলি চালাতে পারে?


125

আমার কাছে কয়েকটি ব্যাচের প্রসেসিংয়ের জন্য পাওয়ারশেল স্ক্রিপ্ট রয়েছে এবং আমি কিছু সমান্তরাল প্রসেসিং করতে চাই। পাওয়ারশেলের মনে হয় কিছু ব্যাকগ্রাউন্ড প্রসেসিং অপশন রয়েছে যেমন স্টার্ট-জব, ওয়েট-জব ইত্যাদি। তবে সমান্তরাল কাজ করার জন্য আমি যে একমাত্র ভাল সংস্থান পেয়েছি তা হ'ল একটি স্ক্রিপ্টের পাঠ্য লিখতে এবং সেগুলি চালিত করা হয়েছিল ( পাওয়ারশেল মাল্টিথ্রেডিং )

আদর্শভাবে, আমি। নেট 4-তে সমান্তরাল ফোর্যাচ করার মতো কিছু চাই।

বেশ সুন্দর লাগার মতো কিছু:

foreach-parallel -threads 4 ($file in (Get-ChildItem $dir))
{
   .. Do Work
}

আমি কেবল সি # তে নেমে যাওয়াই ভাল ছিলাম ...


tl; dr: receive-job (wait-job ($a = start-job { "heyo!" })); remove-job $a অথবা $a = start-job { "heyo!" }; wait-job $a; receive-job $a; remove-job $aএও নোট করুন যে receive-jobকাজ শেষ হওয়ার আগে আপনি কল করলে আপনি কিছুই পেতে পারেন না।
অ্যান্ড্রু

এছাড়াও(get-job $a).jobstateinfo.state;
অ্যান্ড্রু

উত্তর:


99

আপনি ব্যাকগ্রাউন্ড জবস ব্যবহার করে পাওয়ারশেল 2 এ সমান্তরাল কাজ সম্পাদন করতে পারেন । পরীক্ষা করে দেখুন স্টার্ট-ইয়োব এবং অন্যান্য কাজ cmdlets।

# Loop through the server list
Get-Content "ServerList.txt" | %{

  # Define what each job does
  $ScriptBlock = {
    param($pipelinePassIn) 
    Test-Path "\\$pipelinePassIn\c`$\Something"
    Start-Sleep 60
  }

  # Execute the jobs in parallel
  Start-Job $ScriptBlock -ArgumentList $_
}

Get-Job

# Wait for it all to complete
While (Get-Job -State "Running")
{
  Start-Sleep 10
}

# Getting the information back from the jobs
Get-Job | Receive-Job

3
তাই আমি এই পরামর্শটি বেশ কয়েকবার চেষ্টা করেছি, তবে মনে হচ্ছে আমার ভেরিয়েবলগুলি সঠিকভাবে প্রসারিত হচ্ছে না। একই লাইনটি ব্যবহার করতে, যখন এই লাইনটি কার্যকর করে: Test-Path "\\$_\c$\Something"আমি $_এটি বর্তমান আইটেমটিতে প্রসারিত হবে বলে আশা করব । তবে তা হয় না। পরিবর্তে এটি একটি খালি মান প্রদান করে। এটি কেবল স্ক্রিপ্ট ব্লকগুলির মধ্যে থেকেই ঘটেছিল বলে মনে হচ্ছে। আমি যদি প্রথম মন্তব্যের অবিলম্বে সেই মানটি লিখি তবে মনে হয় এটি সঠিকভাবে কাজ করবে।
rjg

1
@ লিকুইড - সাইটের জন্য পৃথক প্রশ্নের মতো শোনায়
স্টিভ টাউনসেন্ড

পটভূমিতে চলমান কাজের আউটপুট আমি কীভাবে দেখতে পারি?
সিম্পলগুই

@SimpleGuy - - আউটপুট গ্রহণ তথ্যের জন্য এখানে দেখতে stackoverflow.com/questions/15605095/... - মত আপনি পটভূমির কাজ সম্পন্ন হয়ে যতক্ষণ না নির্ভরযোগ্যভাবে এই দেখতে পারেন বলে মনে হচ্ছে না।
স্টিভ টাউনসেন্ড

@ স্টিভটাউনসেন্ড ধন্যবাদ! আসলে আউটপুট দেখা পর্দায় খুব ভাল না। দেরি করে আসে, তাই আমার পক্ষে কাজে লাগে না। পরিবর্তে আমি নতুন টার্মিনালে (শেল) একটি প্রক্রিয়া শুরু করেছি, সুতরাং এখন প্রতিটি প্রক্রিয়া বিভিন্ন টার্মিনালে চলছে যা অগ্রগতির দর্শনকে আরও উন্নত ও ক্লিনার দিয়ে দেয়।
সিম্পলগুই

98

স্টিভ টাউনসেন্ডের উত্তর তাত্ত্বিকভাবে সঠিক তবে @ লিঙ্কভিড উল্লেখ করেছেন হিসাবে বাস্তবে নয়। আমার সংশোধিত কোড জব-প্রসঙ্গের বাধা বিবেচনা করে - কোনও কিছুই এই বাধাটিকে ডিফল্টরূপে অতিক্রম করে না! স্বয়ংক্রিয় $_ভেরিয়েবলটি লুপে ব্যবহার করা যেতে পারে তবে স্ক্রিপ্ট ব্লকের মধ্যে সরাসরি ব্যবহার করা যায় না কারণ এটি কাজ দ্বারা তৈরি করা একটি পৃথক প্রসঙ্গে রয়েছে।

সন্তানের প্রসঙ্গে প্রাসঙ্গিক প্রসঙ্গ থেকে ভেরিয়েবলগুলি পাস করার জন্য, এটি পাঠাতে -ArgumentListপ্যারামিটারটি ব্যবহার করুন Start-Jobএবং paramএটি পাওয়ার জন্য স্ক্রিপ্ট ব্লকের ভিতরে ব্যবহার করুন ।

cls
# Send in two root directory names, one that exists and one that does not.
# Should then get a "True" and a "False" result out the end.
"temp", "foo" | %{

  $ScriptBlock = {
    # accept the loop variable across the job-context barrier
    param($name) 
    # Show the loop variable has made it through!
    Write-Host "[processing '$name' inside the job]"
    # Execute a command
    Test-Path "\$name"
    # Just wait for a bit...
    Start-Sleep 5
  }

  # Show the loop variable here is correct
  Write-Host "processing $_..."

  # pass the loop variable across the job-context barrier
  Start-Job $ScriptBlock -ArgumentList $_
}

# Wait for all to complete
While (Get-Job -State "Running") { Start-Sleep 2 }

# Display output from all jobs
Get-Job | Receive-Job

# Cleanup
Remove-Job *

(আমি সাধারন প্রমাণ হিসাবে পাওয়ারশেল ডকুমেন্টেশনের একটি রেফারেন্স সরবরাহ করতে চাই তবে হায়, আমার সন্ধানটি ফলহীন ছিল context প্রসঙ্গ বিচ্ছেদ কোথায় ডকুমেন্ট হয় তা যদি আপনি যদি জানতে পারেন তবে আমাকে জানাতে এখানে একটি মন্তব্য পোস্ট করুন!)


এই উত্তরের জন্য ধন্যবাদ। আমি আপনার সমাধানটি ব্যবহার করার চেষ্টা করেছি, তবে আমি এটি সম্পূর্ণরূপে কাজ করতে পারিনি। আপনি কি এখানে আমার প্রশ্নটি একবার দেখে নিতে পারেন: স্ট্যাকওভারফ্লো
ডেভিড বলেছেন পুনরুদ্ধার মনিকা

বিকল্পভাবে, এটি পৃথক স্ক্রিপ্ট ফাইল চাওয়া বেশ সহজ। কেবল ব্যবহার করুনStart-Job -FilePath script.ps1 -ArgumentList $_
চাদ জাভিস্টোস্কি

বিকল্প পদ্ধতি হ'ল স্ক্রিপ্ট জেনারেশনের প্রাথমিক পাস করা, যেখানে পরিবর্তনশীল সম্প্রসারণ ছাড়া আর কিছুই করা হচ্ছে না এবং এরপরে উত্পন্ন স্ক্রিপ্টগুলিকে সমান্তরালে আহ্বান জানাতে হবে। আমার কাছে একটি ছোট সরঞ্জাম রয়েছে যা স্ক্রিপ্ট জেনারেশনের সাথে মানিয়ে নিতে পারে, যদিও এটি কখনও স্ক্রিপ্ট জেনারেশনকে সমর্থন করার উদ্দেশ্যে নয়। আপনি এটি এখানে দেখতে পারেন ।
ওয়াল্টার মিট্টি

এইটা কাজ করে. তবে আমি স্ক্রিপ্টব্লক থেকে সরাসরি ফিড আউটপুট স্ট্রিম পেতে পারি না। স্ক্রিপ্টব্লক ফিরে এলে আউটপুট কেবল মুদ্রিত হয়।
vothaison

8

http://gallery.technet.microsoft.com/scriptcenter/Invoke-Async-Allows-you-to-83b0c9f0

আমি একটি ইনভোক-অ্যাসিঙ্ক তৈরি করেছি যা আপনাকে একই সাথে একাধিক স্ক্রিপ্ট ব্লক / সেমিডলেট / ফাংশন পরিচালনা করতে দেয়। এটি ছোট চাকরির জন্য দুর্দান্ত (100 টি মেশিনের বিপরীতে সাবনেট স্ক্যান বা ডাব্লুআইএমআই কোয়েরি) কারণ স্টার্ট-জব স্টার্টআপ সময় বনাম রানস্পেস তৈরির জন্য ওভারহেডটি বেশ কঠোর। এটি যেমন ব্যবহার করা যেতে পারে।

লিপি ব্লক সহ,

$sb = [scriptblock] {param($system) gwmi win32_operatingsystem -ComputerName $system | select csname,caption} 

$servers = Get-Content servers.txt 

$rtn = Invoke-Async -Set $server -SetParam system  -ScriptBlock $sb

just cmdlet / ফাংশন

$servers = Get-Content servers.txt 

$rtn = Invoke-Async -Set $servers -SetParam computername -Params @{count=1} -Cmdlet Test-Connection -ThreadCount 50

8

এই দিনগুলিতে এর অনেকগুলি উত্তর রয়েছে:

  1. কাজ (বা PS 6/7 বা মডিউলে থ্রেডজবস)
  2. স্টার্ট প্রক্রিয়া
  3. কর্মপ্রবাহ
  4. অন্য রান স্পেসের সাথে পাওয়ারশেল এপিআই
  5. একাধিক কম্পিউটারের সাথে আহ্বান-কমান্ড, যা সমস্ত লোকালহোস্ট হতে পারে (প্রশাসক হতে হবে)
  6. আইএসইতে একাধিক সেশন (রানস্পেস) ট্যাব বা দূরবর্তী পাওয়ারশেল আইএসই ট্যাব
  7. পাওয়ারশেল 7 এর foreach-object -parallel# 4 এর বিকল্প হিসাবে রয়েছে

আক্ষরিক অর্থে একটি পূর্বাভাসের সাথে এখানে ওয়ার্কফ্লোস রয়েছে: সমান্তরাল:

workflow work {
  foreach -parallel ($i in 1..3) { 
    sleep 5 
    "$i done" 
  }
}

work

3 done
1 done
2 done

বা একটি সমান্তরাল ব্লক সহ একটি ওয়ার্কফ্লো:

function sleepfor($time) { sleep $time; "sleepfor $time done"}

workflow work {
  parallel {
    sleepfor 3
    sleepfor 2
    sleepfor 1
  }
  'hi'
}

work 

sleepfor 1 done
sleepfor 2 done
sleepfor 3 done
hi

রানস্পেসের উদাহরণ সহ একটি এপিআই এখানে রয়েছে:

$a =  [PowerShell]::Create().AddScript{sleep 5;'a done'}
$b =  [PowerShell]::Create().AddScript{sleep 5;'b done'}
$c =  [PowerShell]::Create().AddScript{sleep 5;'c done'}
$r1,$r2,$r3 = ($a,$b,$c).begininvoke() # run in background
$a.EndInvoke($r1); $b.EndInvoke($r2); $c.EndInvoke($r3) # wait
($a,$b,$c).streams.error # check for errors
($a,$b,$c).dispose() # clean

a done
b done
c done

7

পটভূমির কাজগুলি সেটআপের জন্য ব্যয়বহুল এবং পুনরায় ব্যবহারযোগ্য নয়। পাওয়ারশেল এমভিপি ওসিন গ্রেহানের একটি ভাল উদাহরণ রয়েছে পাওয়ারশেল মাল্টি-থ্রেডিংয়ের রয়েছে।

(10/25/2010 সাইটটি ডাউন আছে তবে ওয়েব আর্কাইভের মাধ্যমে অ্যাক্সেসযোগ্য)।

আমি এখানে ডেটা লোডিং রুটিনে ব্যবহারের জন্য অভিযোজিত ওসিন স্ক্রিপ্ট ব্যবহার করেছি:

http://rsdd.codeplex.com/SourceControl/changeset/view/a6cd657ea2be#Invoke-RSDDThreaded.ps1


এই উত্তরের জন্য লিঙ্ক পচা সেট হয়েছে
লুক

4

পূর্ববর্তী উত্তরগুলি সম্পূর্ণ করতে, আপনি Wait-Jobসমস্ত কাজ শেষ হওয়ার জন্য অপেক্ষা করতেও ব্যবহার করতে পারেন :

For ($i=1; $i -le 3; $i++) {
    $ScriptBlock = {
        Param (
            [string] [Parameter(Mandatory=$true)] $increment
        )

        Write-Host $increment
    }

    Start-Job $ScriptBlock -ArgumentList $i
}

Get-Job | Wait-Job | Receive-Job

0

PowerShell 7 এ আপনি ব্যবহার করতে পারেন foreach-বস্তুর -Parallel

$Message = "Output:"
Get-ChildItem $dir | ForEach-Object -Parallel {
    "$using:Message $_"
} -ThrottleLimit 4

0

আপনি যদি সর্বশেষ ক্রস প্ল্যাটফর্ম পাওয়ারশেল ব্যবহার করেন (যা আপনাকে বিটিডব্লিউ করা উচিত) https://github.com/powershell/powershell#get-powershell , আপনি &সমান্তরাল স্ক্রিপ্টগুলি চালানোর জন্য একক যুক্ত করতে পারেন । (ব্যবহারের; ধারাবাহিকভাবে চালানোর জন্য )

আমার ক্ষেত্রে আমার সমান্তরালভাবে 2 এনপিএম স্ক্রিপ্টগুলি চালানো দরকার: npm run hotReload & npm run dev


আপনি powershellএর স্ক্রিপ্টগুলির জন্য এনপিএম সেটআপ করতে পারেন (ডিফল্টরূপে এটি cmdউইন্ডোতে ব্যবহৃত হয়)।

প্রকল্পের রুট ফোল্ডার থেকে চালান: npm config set script-shell pwsh --userconfig ./.npmrc এবং তারপরে একক এনপিএম স্ক্রিপ্ট কমান্ডটি ব্যবহার করুন:npm run start

"start":"npm run hotReload & npm run dev"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.