Çok iş parçacıklı Windows FOR toplu iş komutu


11

birden çok iş parçacığında toplu iş dosyasında FOR komutunu çalıştırmak için basit bir yolu olup olmadığını biliyor musunuz ? Görevlerimi 4 paralel iş parçacığında çalıştıramazsam 4 çekirdeğe sahip olmanın anlamı nedir?

Örneğin, PNG'leri PNGOUT ile optimize edersem, kullanacağım komut

for %i in (*.png) do pngout "%i"

Ancak bu, alt görevlerin birbirine hiç bağlı olmadığı oldukça paraleleştirilebilir bir görevdir.

Bunu 4 'kuyrukta' çalıştırmak için şöyle bir şey yazardım

for -thread 4 %i in (*.png) do pngout "%i"

Bunu yapabilen veya mevcut ücretsiz bir çözüm var mı gibi kendi benzeri bir uygulama yazmam gerekiyor mu?


harici bir aracı kullanarak aşağıdaki cevabı kontrol edin: [ stackoverflow.com/a/12041213/365229
Karışık

Yanıtlar:


13

Bir süre önce Yığın Taşması: Kabuk işlemlerinin paralel yürütülmesi için yalnızca en fazla sayıda komut yürüten bir toplu iş dosyası yazdım :

@echo off
for /l %%i in (1,1,20) do call :loop %%i
goto :eof

:loop
call :checkinstances
if %INSTANCES% LSS 5 (
    rem just a dummy program that waits instead of doing useful stuff
    rem but suffices for now
    echo Starting processing instance for %1
    start /min wait.exe 5 sec
    goto :eof
)
rem wait a second, can be adjusted with -w (-n 2 because the first ping returns immediately;
rem otherwise just use an address that's unused and -n 1)
echo Waiting for instances to close ...
ping -n 2 ::1 >nul 2>&1
rem jump back to see whether we can spawn a new process now
goto loop
goto :eof

:checkinstances
rem this could probably be done better. But INSTANCES should contain the number of running instances afterwards.
for /f "usebackq" %%t in (`tasklist /fo csv /fi "imagename eq wait.exe"^|find /v /c ""`) do set INSTANCES=%%t
goto :eof

Paralel ve en aza indirilen en fazla dört yeni işlem oluşturur. Her bir işlemin ne kadar sürdüğüne ve ne kadar sürdüğüne bağlı olarak, bekleme süresinin muhtemelen ayarlanması gerekir. Başka bir şey yapıyorsanız muhtemelen görev listesinin aradığı işlem adını da ayarlamanız gerekir.

Bununla birlikte, bu parti tarafından ortaya çıkan süreçleri doğru bir şekilde saymanın bir yolu yoktur. Bunun bir yolu, toplu %RANDOM%işin ( ) başında rastgele bir sayı oluşturmak ve işlemeyi gerçekleştiren (veya işleme programını üreten) ancak pencere başlığını bir parametreye ayarlayabilen yardımcı bir toplu iş oluşturmaktır:

@echo off
title %1
"%2" "%3"

Bu, başlığını ilk parametreye ayarlayan ve sonra ikinci parametreyi üçüncü ile bağımsız değişken olarak çalıştıran basit bir toplu iş olacaktır. Daha sonra yalnızca belirtilen pencere başlığına ( tasklist /fi "windowtitle eq ...") sahip işlemleri seçerek görev listesinde filtreleme yapabilirsiniz . Bu oldukça güvenilir olmalı ve çok fazla yanlış pozitifliği önlemelidir. cmd.exeHala çalışan bazı örnekleriniz varsa arama yapmak kötü bir fikir olacaktır, çünkü bu, çalışan işlemleri havuzunuzu sınırlar.

%NUMBER_OF_PROCESSORS%Kaç tane örnek doğacağının mantıklı bir varsayılanını oluşturmak için kullanabilirsiniz .

psexecİşlemleri uzaktan oluşturmak için bunu kolayca uyarlayabilirsiniz (ancak diğer makinede yönetici ayrıcalıklarına sahip olmanız ve toplu olarak parola sağlamanız gerektiğinden çok uygun olmaz). Yine de, filtreleme için işlem adlarını kullanmanız gerekir.


Bu bazı ciddi kara toplu sihir! Keşke daha fazla oy verebilseydim!
Axarydax

Hayır, onu astıktan sonra bu oldukça basit şeyler ;-)
Joey

'Wc' komutu Win10 komut satırımda yok. Başka ne kullanabilirim?
PeterCo

1
@PeterCo: find /c /v "".
Joey

1

Toplu iş dosyaları son derece temel komut dosyaları içindir ve herhangi bir çoklu iş parçacığını desteklemez. Yapmak istediğinizi yapmak için kendi yardımcı programınızı yazmanız gerekir.

Alternatif olarak, Windows PowerShell sizi hedefinize yaklaştıracak daha fazla özellik sağlayabilir.

Aynı anda birden çok işlemi çalıştırmak istiyorsanız , PNGOUT yardımcı programını yeni bir pencerede başlatmak için start komutunu kullanabilirsiniz . FOR döngüsü daha sonra her işlemi bitirmek için beklemeden devam edecektir.

Değiştirilen çizgi şöyle görünecektir:

for %i in (*.png) do start pngout "%i"

Ancak, bunun aynı anda dizindeki TÜM dosyalar için PNGOUT'u etkin bir şekilde başlatacağını unutmayın; bu büyük olasılıkla istenmez.


Bu naif bir yaklaşım ve bahsettiğiniz gibi muhtemelen arzu edilemez. Sadece çekirdekleriniz kadar süreç başlatmak istiyorsunuz. 4 çekirdeğiniz ve 1.000 dosyanız varsa, 1000'in tamamı işlenene kadar bir kerede yalnızca 4 işlemek istersiniz. 4 çekirdeğe aynı anda 1.000'i işlemeye çalışırsanız, bilgisayarınız işe yaramaz bir taramayı yavaşlatır.
Adisak
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.