Lệnh Windows FOR đa luồng


11

Bạn có biết nếu có một cách đơn giản để chạy lệnh FOR trong tệp bó trên nhiều luồng không? Điểm có 4 lõi là gì nếu tôi không thể chạy các tác vụ của mình trong 4 luồng song song?

Ví dụ: nếu tôi tối ưu hóa PNG bằng PNGOUT, lệnh tôi sẽ sử dụng là

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

Nhưng đây là nhiệm vụ rất tương đương trong đó các nhiệm vụ phụ hoàn toàn không phụ thuộc vào nhau.

Để chạy cái này trong 4 'hàng đợi' Tôi sẽ viết một cái gì đó như

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

Tôi có cần phải viết ứng dụng tương tự của riêng mình để có thể làm điều này hoặc có sẵn giải pháp miễn phí không?


kiểm tra câu trả lời cho việc sử dụng công cụ bên ngoài: [ stackoverflow.com/a/12041213/365229[[1] [1]: stackoverflow.com/a/12041213/365229
Behrouz.M

Câu trả lời:


13

Tôi đã viết một tệp bó chỉ thực hiện một số lượng lệnh tối đa một lúc trước trên Stack Overflow: Thực thi song song các quy trình shell :

@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

Nó sinh ra tối đa bốn quy trình mới thực hiện song song và giảm thiểu. Thời gian chờ có lẽ cần được điều chỉnh, tùy thuộc vào mỗi quá trình thực hiện và thời gian chạy. Có lẽ bạn cũng cần điều chỉnh tên quy trình mà danh sách tác vụ đang tìm nếu bạn đang làm gì đó.

Mặc dù vậy, không có cách nào để đếm đúng các quy trình được sinh ra bởi đợt này. Một cách là tạo một số ngẫu nhiên khi bắt đầu lô ( %RANDOM%) và tạo một lô trợ giúp thực hiện xử lý (hoặc sinh ra chương trình xử lý) nhưng có thể đặt tiêu đề cửa sổ của nó thành một tham số:

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

Đây sẽ là một lô đơn giản đặt tiêu đề của nó thành tham số đầu tiên và sau đó chạy tham số thứ hai với tham số thứ ba làm đối số. Sau đó, bạn có thể lọc trong danh sách tác vụ bằng cách chỉ chọn các quy trình có tiêu đề cửa sổ được chỉ định ( tasklist /fi "windowtitle eq ..."). Điều này sẽ hoạt động khá đáng tin cậy và ngăn ngừa quá nhiều tích cực sai. Tìm kiếm cmd.exesẽ là một ý tưởng tồi nếu bạn vẫn còn một số trường hợp đang chạy, vì điều đó giới hạn nhóm quy trình công nhân của bạn.

Bạn có thể sử dụng %NUMBER_OF_PROCESSORS%để tạo một mặc định hợp lý về số lượng cá thể sinh sản.

Bạn cũng có thể dễ dàng điều chỉnh việc này để sử dụng psexecđể sinh ra các quy trình từ xa (nhưng sẽ không khả thi vì bạn phải có đặc quyền quản trị viên trên máy khác cũng như cung cấp mật khẩu theo đợt). Tuy nhiên, bạn sẽ phải sử dụng tên quy trình để lọc.


Đây là một số ma thuật lô đen nghiêm trọng! Tôi ước tôi có thể upvote nhiều lần hơn!
Axarydax

Không, đó là những thứ khá cơ bản một khi bạn hiểu rõ về nó ;-)
Joey

Lệnh 'wc' không khả dụng trong dòng lệnh Win10 của tôi. Tôi có thể sử dụng cái gì khác?
PeterCo

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

1

Các tệp hàng loạt dành cho kịch bản cực kỳ cơ bản và không hỗ trợ bất kỳ loại đa luồng nào. Bạn sẽ cần phải viết tiện ích của riêng bạn để làm những gì bạn muốn thực hiện.

Ngoài ra, Windows PowerShell có thể cung cấp nhiều khả năng hơn để giúp bạn đến gần hơn với mục tiêu của mình.

Nếu bạn chỉ đơn giản muốn chạy nhiều hoạt động cùng một lúc, bạn có thể sử dụng lệnh bắt đầu để khởi chạy tiện ích PNGOUT trong một cửa sổ mới. Vòng lặp FOR sau đó sẽ tiếp tục mà không cần chờ đợi trên mỗi thao tác để kết thúc.

Dòng sửa đổi sẽ trông như thế này:

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

Tuy nhiên, lưu ý rằng điều này sẽ khởi chạy hiệu quả PNGOUT cho TẤT CẢ các tệp trong thư mục cùng một lúc, điều này rất có thể không mong muốn.


Đây là một cách tiếp cận ngây thơ và như bạn đề cập có lẽ không được mong muốn. Bạn chỉ muốn khởi chạy nhiều tiến trình như bạn có lõi. Nếu bạn có 4 lõi và 1.000 tệp, bạn thực sự chỉ muốn xử lý 4 lần cho đến khi tất cả 1.000 được xử lý. Nếu bạn cố gắng xử lý tất cả 1.000 cùng một lúc trên 4 lõi, máy tính của bạn sẽ chậm để thu thập dữ liệu vô dụng.
Adisak
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.