1

Тема: VBS: Запуск нескольких функций одновременно

Есть скрипт в нем запускается функция с параметром1, возможно ли не дожидаясь завершения функции с параметром1 запустить функцию с параметром2.

Решение есть и оно заключается в использовании WshShell.Run или WshShell.Exec, но здесь получается придется использовать дополнительный скрипт который будет запускаться с параметрами в отдельном окне, а так бы был один скрипт с разными функциями.

2

Re: VBS: Запуск нескольких функций одновременно

Нет.

3

Re: VBS: Запуск нескольких функций одновременно

Если позволяют условия задачи, то как вариант: скрипт перевести на основу hta-приложения.

А там уже есть возможность сделать "отложенный" запуск через энное количество милисекунд одновременно нескольких экземпляров своей функции с разными параметрами - погуглите "hta window.settimeout".

WBR. Roman

4 (изменено: wildwolf007, 2014-03-14 13:04:28)

Re: VBS: Запуск нескольких функций одновременно

Спасибо интересное решение попробую с ним разобраться. На будущее.

alexii нашел немного извратное решение, но вроде рабочее и хоть какой-то но параллелизм выполнения функций при помощи одного файла скрипта.

Решил проблему при помощи простановке в начале скрипта проверки по аргументу, если условие не сработало не по какому аргументу, то идет стандартное выполнение скрипта обычный запуск, если сработало условие и был послан какой-то определенный аргумент, то производится запуск определенной функции или одной и той же функции с разными параметрами и все выполняется параллельно. Самое главное ограничить количество таких запусков.

благодаря WshShell.Exec можно отслеживать каждый такой запущенный процесс и управлять им.

Если нужны будут разъяснения чуть позже выложу расписанное все.

5 (изменено: Евген, 2014-03-14 13:46:09)

Re: VBS: Запуск нескольких функций одновременно

Погодите, погодите...
позвольте отписаться )))
Как то очень давненько мы с Вами обсуждали задачу по распаралеливание запуска скрипта на удалённых хостах, я тогда предложил и реализовал организацию паралельных потоков как раз путём многократного запуска самого себя из самого себя (скрипта) с разными аргументами, тем самым достигнув многопоточности.

Может быть здесь такое же решение подойдёт ?

Вопрос конечно в том, что те потоки не очень то контролируемые будут, но имхо это какое-никакое решение...

Времени не хватает... :-(

6

Re: VBS: Запуск нескольких функций одновременно

Евген пишет:

Погодите, погодите...
позвольте отписаться )))
Как то очень давненько мы с Вами обсуждали задачу по распаралеливание запуска скрипта на удалённых хостах, я тогда предложил и реализовал организацию паралельных потоков как раз путём многократного запуска самого себя из самого себя (скрипта) с разными аргументами, тем самым достигнув многопоточности.

Может быть здесь такое же решение подойдёт ?

Вопрос конечно в том, что те потоки не очень то контролируемые будут, но имхо это какое-никакое решение...

Не припоминаю или это было с батниками ?

Здесь процессы становятся управляемыми т.к. используем Exec. Сейчас попробую расписать.

7

Re: VBS: Запуск нескольких функций одновременно

У кого есть что можно выполнить в несколько процессов ? Загрузить скрипт какими-то данными ?

Выполнять только в консоле, а то будет много окошечек.

Нужно исправить только путь к скрипту PutProcessVBS = "F:\System\Request\Parallel.vbs"



Dim WshArguments, i, list,parametr

list=""

'Получаем доступ к коллекции через свойство Arguments
set WshArguments=WScript.Arguments

'Определяем, есть ли передача параметров
if WshArguments.count()<>0 then
    
    ' Производим перебор коллекции
    for i=0 to WshArguments.Count-1
        If WshArguments(i) = 0 Then
            WScript.Quit
        Else
            list = list & WshArguments(i) & vbCrLf        
            parametr = 1
        End If
    next
    If parametr = 1 Then
        Process list
        WScript.Quit
    End If
End if


PutProcessVBS = "F:\System\Request\Parallel.vbs"

PathCscript = "%WINDIR%\System32\cscript.exe"

TimeRepeat = 5000

'Протапливаем процессы с нулевым значением для простановки статуса равной 1
set WshShell = WScript.CreateObject("WScript.Shell")
ProcessClients = PathCscript &" " &PutProcessVBS &" " &"0"
set WshExec_1 = WshShell.Exec(ProcessClients)
WshExec_1.Terminate()
set WshExec_2 = WshShell.Exec(ProcessClients)
WshExec_2.Terminate()
set WshExec_3 = WshShell.Exec(ProcessClients)
WshExec_3.Terminate()
set WshExec_4 = WshShell.Exec(ProcessClients)
WshExec_4.Terminate()
set WshExec_5 = WshShell.Exec(ProcessClients)
WshExec_5.Terminate()




Do

    if WshExec_1.Status = 1 then 
        Dim ProcessClients1
        ProcessClients1 = PathCscript &" " &PutProcessVBS &" " &"1"
        set WshExec_1 = WshShell.Exec(ProcessClients1)
    End If
    
    if WshExec_2.Status = 1 then 
        Dim ProcessClients2
        ProcessClients2 = PathCscript &" " &PutProcessVBS &" " &"2"
        set WshExec_2 = WshShell.Exec(ProcessClients2)
    End If
    
    if WshExec_3.Status = 1 then 
        Dim ProcessClients3
        ProcessClients3 = PathCscript &" " &PutProcessVBS &" " &"3"
        set WshExec_3 = WshShell.Exec(ProcessClients3)
    End If
    
    if WshExec_4.Status = 1 then 
        Dim ProcessClients4
        ProcessClients4 = PathCscript &" " &PutProcessVBS &" " &"4"
        set WshExec_4 = WshShell.Exec(ProcessClients4)
    End If
    
    if WshExec_5.Status = 1 then 
        Dim ProcessClients5
        ProcessClients5 = PathCscript &" " &PutProcessVBS &" " &"5"
        set WshExec_5 = WshShell.Exec(ProcessClients5)
    End If    

    WScript.Echo Date
    WScript.Echo time
    WScript.Echo "Запрос принят"
    WScript.Echo "Следующий запуск через " &TimeRepeat &" ms"
    WScript.Sleep TimeRepeat
    Cls

Loop While Close = 0

'Процедура очистки экрана cls
Sub Cls()
Set WshShell = CreateObject("WScript.Shell")
    WshShell.Exec("mode.com con: lines=0").StdOut.ReadAll
End Sub




' Функция для параллельного выполнения нужно как-то загрузить ее что уж точно перепроверить все
Function Process(Data)

i=data+1
MsgBox Data &i
MsgBox 1112


End Function




Хотя можно будет для каждого процесса установить свою логику.

8

Re: VBS: Запуск нескольких функций одновременно

В чём глубинный смысл:

set WshExec_1 = WshShell.Exec(ProcessClients)
WshExec_1.Terminate()

?!

9

Re: VBS: Запуск нескольких функций одновременно

Евген, а Вы на каком форуме были и с каким ником? Эта задача у меня уже давненько висит.

10 (изменено: wildwolf007, 2014-03-14 14:29:37)

Re: VBS: Запуск нескольких функций одновременно

alexii пишет:

В чём глубинный смысл:

set WshExec_1 = WshShell.Exec(ProcessClients)
WshExec_1.Terminate()

?!


Проставить Status равный 1 в цикле запуск проходит только того процесса который свободен.
Не спорю может как-то можно было по другому поставить это значение, пока по другому не придумал.

Управление по каждому процессу:
0 - запущен
1 - закрыт

11

Re: VBS: Запуск нескольких функций одновременно

Проставить Status равный 1 в цикле запуск проходит только того процесса который свободен.

Переведите на русский, пожалуйста.

12

Re: VBS: Запуск нескольких функций одновременно

Хотел быстро ответить.

Если не будет  этой строки то статус будет не определен и условие не будет срабатывать.

    if WshExec_1.Status = 1 then
        Dim ProcessClients1
        ProcessClients1 = PathCscript &" " &PutProcessVBS &" " &"1"
        set WshExec_1 = WshShell.Exec(ProcessClients1)
    End If

13

Re: VBS: Запуск нескольких функций одновременно

Допустим поступил какой-то большой запрос на который нужно потратить N количество времени благодаря Status можно определить какой процесс сейчас свободен и тогда данному процессу поручить выполнение этого запроса.

Пока данный запрос выполняется ему проставляется статус 0 как закончит выполнятся проставится статус 1

Если в процессе выполнения поступит так же большой запрос, то занятому процессу данный запрос не будет передан, будет передан свободному процессу или будет ждать пока какой-то процесс освободится.

Если я этого не сделаю вначале то у меня данный статус не будет определен.

Фух вроде объяснил.

14

Re: VBS: Запуск нескольких функций одновременно

Оптимизация сценариев
Из своего архива:

'Файл tasks.vbs
Option Explicit
Const ForReading = 1
Const fsuffix = "_failed"
Const ScriptLimit = 50, TimeOut = 15
Dim Args, oShell, fso, oHostFile, oFailHostFile
Dim aHostList(), aScripts(), aHosts(), aTimes()
Dim strScript, strHostFile, strFailHostFile, strArguments

Sub UsageBox
MsgBox "General syntax:" & vbCrLf & _
"tasks.vbs <script_name.extension> <hosts file> [list of arguments] ... ", _
vbOKOnly + vbInformation
End Sub

Sub ErrorBox
MsgBox "Error " & Err.Number & ": " & Err.Description, vbOKOnly + vbExclamation
Err.Clear
End Sub

Sub DoneBox
MsgBox "All done! ", vbOKOnly + vbInformation
End Sub

Sub LogFail(strHost)
oFailHostFile.WriteLine strHost
End Sub

Sub RunTasks
Dim i, n, bEmpty, intMaxScript, intMaxHostList
intMaxScript = ScriptLimit - 1
intMaxHostList = UBound(aHostList)
If intMaxHostList < intMaxScript Then intMaxScript = intMaxHostList
ReDim aScripts(intMaxHostList), aHosts(intMaxHostList), aTimes(intMaxHostList)
n = 0
For i = 0 To intMaxScript
  aTimes(i) = 0
Next
bEmpty = True
Do
If Not bEmpty Then Wscript.Sleep 1000
bEmpty = True
  For i = 0 To intMaxScript
    If aTimes(i) = 0 Then
      If n <= intMaxHostList Then
        aTimes(i) = 1
        aHosts(i) = aHostList(n)
        Set aScripts(i) = oShell.Exec("wscript.exe " & strScript & " " & _
                          aHosts(i) & strArguments)
        n = n + 1
      End If
    ElseIf aTimes(i) = TimeOut Then
      If aScripts(i).Status = 0 Then aScripts(i).Terminate
      LogFail(aHosts(i))
      aTimes(i) = 0
    Else
      If aScripts(i).Status = 0 Then
        aTimes(i) = aTimes(i) + 1
      Else
        If aScripts(i).ExitCode <> 0 Then LogFail(aHosts(i))
        aTimes(i) = 0
      End If
    End If
    If aTimes(i) > 0 Then bEmpty = False
  Next 
Loop Until bEmpty
End Sub

Sub ProcFiles
Dim i, strHost, errRun
On Error Resume Next
errRun = oShell.Run("wscript.exe " & strScript, 0, True)
If errRun = 9 Then
  Set fso = CreateObject("Scripting.FileSystemObject")
  Set oHostFile = fso.OpenTextFile(strHostFile, ForReading, False)
  If Err.Number = 0 Then
    Set oFailHostFile = fso.CreateTextFile(strFailHostFile, True)
    If Err.Number = 0 Then
      i = 0
      Do Until oHostFile.AtEndOfStream
        strHost = oHostFile.ReadLine
        If Len(strHost) > 0 Then
          ReDim Preserve aHostList(i)
          aHostList(i) = strHost
          i = i + 1
        End If
      Loop
      oHostFile.Close
      If i > 0 Then RunTasks
      oFailHostFile.Close
      DoneBox
    Else
      ErrorBox
    End If
  Else
    ErrorBox
  End If 
End If
End Sub

Dim i, lenH, dotH
Set Args = Wscript.Arguments
If Args.Count > 1 Then 
  strScript = Args(0)
  strHostFile = Args(1)
  strArguments = ""
  For i = 2 To Args.Count - 1
    strArguments = strArguments & " " & Args(i)
  Next
  dotH = InStrRev(strHostFile, ".")
  lenH = Len(strHostFile)
  If dotH = 0 Then
    strFailHostFile = strHostFile & fsuffix
  Else
    strFailHostFile = Left(strHostFile, dotH - 1) & fsuffix & _
                      Right(strHostFile, lenH - dotH +1)
  End If
  Set oShell = WScript.CreateObject("WScript.Shell")
  ProcFiles
Else
  UsageBox
End If

15

Re: VBS: Запуск нескольких функций одновременно

runjobs: An XP Automation Tool for Parallel Processing of GAMS Jobs

16

Re: VBS: Запуск нескольких функций одновременно

Прошу прощения, а можно пару комментариев по материалам которые Вы показываете? По коду?
В частности какие данные обрабатываются?

17 (изменено: badik, 2014-03-14 15:36:44)

Re: VBS: Запуск нескольких функций одновременно

Основная идея:
1.Организутся массив из N -элементов - максимальное число обрабатываемых процессов
2.элементу массива присваиваем   wshShell.Exec(CmdLine)
    процесс выполняется в фоновом режиме
3. Контролируем  выполнение.
4. Если процесс закончился читаем результат
5. Запускаем следущую команду. пп 2.

Идеи с этих статей я использовал когда то в своем копировщике (Jscript).
У меня было 370 входных папок,140 выходных разбитых на 30 потоков с разной величиной паузы.
Одновременно работало не более 10 процессов.

18

Re: VBS: Запуск нескольких функций одновременно

Если не будет  этой строки

Причём ту «эта строка»? Я спрашивал в чём смысл:

set WshExec_1 = WshShell.Exec(ProcessClients)
WshExec_1.Terminate()

— запустили процесс и тут же его убили?

19

Re: VBS: Запуск нескольких функций одновременно

Спасибо. А я сегодня весь день убил пока разобрался, а оказывается уже все давно изобретено.

20

Re: VBS: Запуск нескольких функций одновременно

alexii пишет:

Если не будет  этой строки

Причём ту «эта строка»? Я спрашивал в чём смысл:

set WshExec_1 = WshShell.Exec(ProcessClients)
WshExec_1.Terminate()

— запустили процесс и тут же его убили?

Статусу процесса .Status был присвоен 1. Можно сказать инициализировал процесс.

21

Re: VBS: Запуск нескольких функций одновременно

Ладно, оставим.

22

Re: VBS: Запуск нескольких функций одновременно

Оставим для чего?

23

Re: VBS: Запуск нескольких функций одновременно

wildwolf007 пишет:

Есть скрипт в нем запускается функция с параметром1, возможно ли не дожидаясь завершения функции с параметром1 запустить функцию с параметром2.

Вероятно, вот это подойдет http://forum.script-coding.com/viewtopi … 388#p74388

Щт Уккщк Куыгьу Туче
’ҐЄгй п Є®¤®ў п бва Ёж : 1251

24

Re: VBS: Запуск нескольких функций одновременно

Скажите имена переменных одни и те же они не будут пересекаться в разных процессах?

25

Re: VBS: Запуск нескольких функций одновременно

wildwolf007 пишет:

Скажите имена переменных одни и те же они не будут пересекаться в разных процессах?

Если из одного скрипта просто запускаются несколько процессов, выполняющих скрипты, то связи между ними никакой нет, ничего не будет пересекаться. Если же организован определенный обмен данными между скриптами - то однозначный ответ можно дать, только посмотрев код сценария.

Щт Уккщк Куыгьу Туче
’ҐЄгй п Є®¤®ў п бва Ёж : 1251

26

Re: VBS: Запуск нескольких функций одновременно

А возможно ли обмениваться между данными процессами. Например создать переменную или массив и в эту переменную или массив могли записывать данные все процессы?

27

Re: VBS: Запуск нескольких функций одновременно

wildwolf007 пишет:

и в эту переменную или массив могли записывать данные все процессы?

Посмотрите выше, я в #23 привел ссылку на пост, пример с обменом данными между процессами прикреплен к нему в файле.

Щт Уккщк Куыгьу Туче
’ҐЄгй п Є®¤®ў п бва Ёж : 1251