1 (изменено: Malcev, 2015-08-05 23:05:34)

Тема: AHK: Асинхронный запуск скриптов

Имеется 5 скриптов, которые в цикле в разное время могут выдать msgbox.
Как сделать так, чтобы 2 msgbox не появились одновременно? (msgbox - только как пример, вместо него может быть, что угодно, например отправка писем)?
Пока родилась такая идея:

loop, 5
{
   fileappend,
   (
      loop
      {
         Random, rand, 3000, 7000
         sleep, `%rand`%
         fileappend, 
         (
            MsgBox,,,,1
         `), test`%A_Index`%`%A_ScriptName`%, UTF-8
      }
   ), script%A_Index%.ahk, UTF-8
   run, script%A_Index%.ahk
}

fileappend,
(
   loop
   {
      loop, test*.ahk,
      {
         RunWait, `%A_LoopFileName`%
         FileDelete, `%A_LoopFileName`%
      }
   }
), check.ahk, UTF-8
run, check.ahk

Может есть способы получше?

2

Re: AHK: Асинхронный запуск скриптов

Непонятно, какая цель всего этого. В чём задача-то?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

3

Re: AHK: Асинхронный запуск скриптов

Информировать через скайп клиентов о готовности их продукта.
Так как через скайп можно передать через коммандную строку только одно сообщение за раз, то нужно сделать подобие очереди.

4

Re: AHK: Асинхронный запуск скриптов

А почему нельзя в одном скрипте циклом через паузу?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

5 (изменено: Malcev, 2015-07-09 17:46:53)

Re: AHK: Асинхронный запуск скриптов

Потому что скрипты работают одновременно.
Они разной направленности.
Какой-то парсит один сайт, какой-то другой.
Я проверял - асинхронный метод winhttprequest в одном скрипте работает медленнее, чем запустить просто несколько скриптов с winhttprequest.

6

Re: AHK: Асинхронный запуск скриптов

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

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

7 (изменено: Irbis, 2015-07-09 18:15:35)

Re: AHK: Асинхронный запуск скриптов

Запустить скрипт-обработчик. А ему передавать можно хоть через буфер,  хоть через Messages, да даже temp-файл сгодится. Были на форуме темы по взаимодействию скриптов.

Upd: Надо взять за правило обновлять тему перед отправкой поста.)

8

Re: AHK: Асинхронный запуск скриптов

Запустить скрипт-обработчик. А ему передавать можно хоть через буфер,  хоть через Messages, да даже temp-файл сгодится.

Через Temp-file я указал в примере.
А можно пример того, как скрипт-обработчик будет ставить их в очередь через Messages?
Допустим 3 исходных скрипта одновременно пошлют ему сообщение, а он приняв их должен будет каждое сообщение по очереди вывести мессаджбоксом и подержать 3 секунды.

9

Re: AHK: Асинхронный запуск скриптов

Я только вечером смогу.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

10 (изменено: Alectric, 2015-07-09 20:04:42)

Re: AHK: Асинхронный запуск скриптов

Решил попробовать.
Главный скрипт:

OnMessage(0x1002,"Function")  ; принимаем сообщение от скриптов.

Loop  ; наверное можно сделать и без цикла, но мне так привычней и надежней.
{
  sleep,1000
  tooltip,% line    ; Осталось парсить эту строку и выдавать разрешение по очереди каждому скрипту.
  loop,parse,line
  {
;    tooltip,% a_loopfield "`n" a_tickcount
    dnes(a_loopfield,1)
    line:=RegExReplace(line, a_loopfield , "")
    gosub,Wait_done  ; ждать завершения.
  }
}


Wait_done:  ; можно принять сообщение о завершении работы для выдачи следующего разрешения.
loop,1000000 ;  ограниченный цикл, если что-то пойдет не так.
{
  sleep,1000
  if done
    break
}
done=
return


Function(wParam,lParam,Msg,hwnd)
{
  global
;  msgbox,%a_tickcount%`n"%wParam%"`n"%lParam%"`n"%Msg%"`n"%hwnd%"

  if wParam=0xff
    done:=lParam
  else
    line.=wParam
}

dnes(index,permission) ; index - номер скрипта, permission - разрешение на продолжение действий.
{
  DetectHiddenWindows,On
  WinGet,Array_id,list,ahk_class AutoHotkey
  Loop,%Array_id%
    sendMessage,0x1003,%Index%,%permission%,,% "ahk_id" Array_id%A_Index%
}

Остальные скрипты:

OnMessage(0x1003,"Function")  ; принимаем сообщение от главного скрипта.

Function(wParam,lParam,Msg,hwnd)
{
  global
;  msgbox,%a_tickcount%`n"%wParam%"`n"%lParam%"`n"%Msg%"`n"%hwnd%"
  if (wParam=1 and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.
  }
  if (wParam=2 and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.
  }
  if (wParam=3 and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.
  }
  if (wParam=4 and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.
  }
  if (wParam=5 and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.
  }
}

dnes(Index,ready) ; index - номер скрипта, ready - ready.
{
  DetectHiddenWindows,On
  WinGet,Array_id,list,ahk_class AutoHotkey
  Loop,%Array_id%
    sendMessage,0x1002,%Index%,%ready%,,% "ahk_id" Array_id%A_Index%
}


!f1::
dnes(1,1) ; говорим главному что готовы встать в очередь.
return

!f2::
dnes(2,1)
return

!f3::
dnes(3,1)
return

!f4::
dnes(4,1)
return

!f5::
dnes(5,1)
return



Win 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

11 (изменено: Alectric, 2015-07-09 19:59:37)

Re: AHK: Асинхронный запуск скриптов

Чуть подправил.
5 штук в одном скрипте - только для теста.

Исправил еще ошибку.

Win 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

12

Re: AHK: Асинхронный запуск скриптов

А если общее число скриптов неизвестно и и нету главного.
Есть n-ое количество скриптов и скрипт-обработчик.
Хотелось бы получить аналогичные действия, что и в моем примере с 1-ого поста, только без использования временных файлов.

13 (изменено: Alectric, 2015-07-09 20:15:39)

Re: AHK: Асинхронный запуск скриптов

Скрипт-обработчик и есть в моем понимании главный скрипт.
Думаю что в любом случае скриптам придется присвоить каждому свой номер, а главный скрипт уже работает с номерами, максимум 0xFE скриптов могут встать в очередь, но можно и больше ведь lParam практически и не используется (единица везде).

Win 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

14 (изменено: Alectric, 2015-07-09 20:14:11)

Re: AHK: Асинхронный запуск скриптов

Т.е. в каждом скрипте должно быть следующее:

ScriptNumber=1

OnMessage(0x1003,"Function")  ; принимаем сообщение от главного скрипта.

Function(wParam,lParam,Msg,hwnd)
{
  global
;  msgbox,%a_tickcount%`n"%wParam%"`n"%lParam%"`n"%Msg%"`n"%hwnd%"
  if (wParam=ScriptNumber and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.
  }
}

dnes(Index,ready)
{
  DetectHiddenWindows,On
  WinGet,Array_id,list,ahk_class AutoHotkey
  Loop,%Array_id%
    sendMessage,0x1002,%Index%,%ready%,,% "ahk_id" Array_id%A_Index%
}

!f1::
dnes(ScriptNumber,1) ; говорим главному что готовы встать в очередь.
return

Где"ScriptNumber" и есть индивидуальный номер скрипта... хотя можно завязать и на имя файла скрипта... как-нибудь... или сделать автоматическое распределение номеров...

Win 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

15

Re: AHK: Асинхронный запуск скриптов

Как-то неправильно он работает.
Создаем 5 скриптов, меняя только ScriptNumber и одновременно запускаем их.
Получаем, не равномерную очередь, а повторяющуюся из одних и тех же скриптов.

OnMessage(0x1003,"Function")  ; принимаем сообщение от главного скрипта.
ScriptNumber=1
loop
{
   dnes(ScriptNumber,1) ; говорим главному что готовы встать в очередь.
   sleep, 1000
}

Function(wParam,lParam,Msg,hwnd)
{
  global
;  msgbox,%a_tickcount%`n"%wParam%"`n"%lParam%"`n"%Msg%"`n"%hwnd%"
  if (wParam=ScriptNumber and lParam=1)
  {
    MsgBox,,,%wParam%,1
    dnes(0xff,1)    ; говорим о завершении работы.
  }
}

dnes(Index,ready)
{
  DetectHiddenWindows,On
  WinGet,Array_id,list,ahk_class AutoHotkey
  Loop,%Array_id%
    sendMessage,0x1002,%Index%,%ready%,,% "ahk_id" Array_id%A_Index%
}

16 (изменено: Alectric, 2015-07-09 20:39:54)

Re: AHK: Асинхронный запуск скриптов

Если все скрипты дают запрос с одинаковым интервалом, то вроде все правильно.

Вот вариант с авто-распределением номеров:
главный:

OnMessage(0x1002,"Function")  ; принимаем сообщение от скриптов.

Loop  ; наверное можно сделать и без цикла, но мне так привычней и надежней.
{
  sleep,1000
  tooltip,% line    ; Осталось парсить эту строку и выдавать разрешение по очереди каждому скрипту.
  loop,parse,line,`,
  {
    if !a_loopfield
      continue
;    msgbox,% a_loopfield "`n" a_tickcount
    dnes(a_loopfield,1)
    line:=RegExReplace(line, a_loopfield "`,", "")
    gosub,Wait_done  ; ждать завершения.
  }
}


Wait_done:  ; можно принять сообзение о завершении работы для выдачи следующего разрешения.
loop,1000000
{
  tooltip,Wait
  sleep,100
  if done
    break
}
done=
return


Function(wParam,lParam,Msg,hwnd)
{
  global
  msgbox,%a_tickcount%`n"%wParam%"`n"%lParam%"`n"%Msg%"`n"%hwnd%"

  if (wParam=0xff and lParam=1)
    done=1
  else if (wParam=0xff and lParam=0xff) ; авто получение номера.
  {
    num++
    dnes(num,0xff) ; отправка номера скрипту.
  }
  else
    line.=wParam "`,"
}

dnes(index,permission) ; index - номер скрипта, permission - разрешение на продолжение действий.
{
  DetectHiddenWindows,On
  WinGet,Array_id,list,ahk_class AutoHotkey
  Loop,%Array_id%
    sendMessage,0x1003,%Index%,%permission%,,% "ahk_id" Array_id%A_Index%
}

Остальные:

OnMessage(0x1003,"Function")  ; принимаем сообщение от главного скрипта.

dnes(0xff,0xff) ; запрос на получение номера

Function(wParam,lParam,Msg,hwnd)
{
  global
;  msgbox,%a_tickcount%`n"%wParam%"`n"%lParam%"`n"%Msg%"`n"%hwnd%"
  if lParam=0xff
    ScriptNumber:=wParam
  if (wParam=ScriptNumber and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.

                                               dnes(ScriptNumber,1) ; следующий запрос.

  }
}

dnes(Index,ready)
{
  DetectHiddenWindows,On
  WinGet,Array_id,list,ahk_class AutoHotkey
  Loop,%Array_id%
    sendMessage,0x1002,%Index%,%ready%,,% "ahk_id" Array_id%A_Index%
}

!f1::
dnes(ScriptNumber,1) ; говорим главному что готовы встать в очередь.
return
Win 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

17 (изменено: Alectric, 2015-07-09 20:37:38)

Re: AHK: Асинхронный запуск скриптов

loop
{
   dnes(ScriptNumber,1) ; говорим главному что готовы встать в очередь.
   sleep, 1000
}

И тут у тебя запросы на очередь отправляются беспрерывно каждую секунду.
А нужно отправить запрос 1 раз и ждать разрешения, затем отправлять еще запрос.

Function(wParam,lParam,Msg,hwnd)
{
  global
;  msgbox,%a_tickcount%`n"%wParam%"`n"%lParam%"`n"%Msg%"`n"%hwnd%"
  if lParam=0xff
    ScriptNumber:=wParam
  if (wParam=ScriptNumber and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.
                                                     dnes(ScriptNumber,1) ; отправляем следующий запрос.
  }
}
Win 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

18 (изменено: serzh82saratov, 2015-07-09 20:48:54)

Re: AHK: Асинхронный запуск скриптов

Если темп файл не устраивает, то я не надеялся бы на очередь сообщений. Думаю если передавать в сообщении текст (WM_COPYDATA), и его добавлять в переменную, а далее её разбирать, удаляя обработанное, то может и получится обработать без потерь довольно большую очередь инструкций.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

19

Re: AHK: Асинхронный запуск скриптов

я не надеялся бы на очередь сообщений.

Почему?
И с Temp file это как?
У меня сейчас создаются скрипты с названием даты времени создания, которые запускаются и удаляются.
Это правильно?

loop, 5
{
   fileappend,
   (
      loop
      {
         Random, rand, 100, 500
         sleep, `%rand`%
         fileappend, 
         (
            MsgBox,,,,1
         `), test`%A_TickCount`%`%A_ScriptName`%, UTF-8
      }
   ), script%A_Index%.ahk, UTF-8
   run, script%A_Index%.ahk
}

fileappend,
(
   loop
   {
      loop, test*.ahk,
      {
         RunWait, `%A_LoopFileName`%
         FileDelete, `%A_LoopFileName`%
      }
   }
), check.ahk, UTF-8
run, check.ahk

20 (изменено: serzh82saratov, 2015-07-09 21:31:30)

Re: AHK: Асинхронный запуск скриптов

Почему?

Там какое то ограничение на память, или кол-во сообщений, но не уверен.

У меня сейчас создаются скрипты с названием даты времени создания, которые запускаются и удаляются.
Это правильно?

Может и пойдёт, сейчас если честно копатся не хочется. Но наверное я бы в один файл дописывал, +посылал бы сообщение об этом. Если в одну милисекунду попасть, то не понятно какой из файлов запишется. А если в этот момент другой пишет в тот же файл, то это можно проверить, и подождать.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

21

Re: AHK: Асинхронный запуск скриптов

serzh82saratov пишет:

не надеялся бы на очередь сообщений.

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

Win 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

22 (изменено: serzh82saratov, 2015-07-09 21:46:30)

Re: AHK: Асинхронный запуск скриптов

Ну да, только речь до сих пор про сообщения. Сможет ли Critical (или какой другой метод) в OnMessage, прервать текущий поток, и хотя бы просто записать текст в переменную, лично для меня больше вопрос практики, а не теории, ибо не подкован.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

23 (изменено: Alectric, 2015-07-09 21:55:07)

Re: AHK: Асинхронный запуск скриптов

Я тоже об этом, уже проверил - не помогает. В качестве альтернативы темп-файлу могу предложить временные данные в реестре, уже делал как-то раз.
Хотя, вроде, реестр это тоже файл где-то в c:\windows.

Win 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

24

Re: AHK: Асинхронный запуск скриптов

Если в одну милисекунду попасть, то не понятно какой из файлов запишется

А кроме милисекунд я еще добавляю имя файла, так что запишутся все.

А если в этот момент другой пишет в тот же файл, то это можно проверить, и подождать

А если они одновременно обратятся к файлу, то что произойдет?

25

Re: AHK: Асинхронный запуск скриптов

В реестре каждый скрипт пишет в свой ключ, мастер файл в момент времени считывает строки и тут же их стирает, затем составляет из них очередь. Нужно обратить внимание что в тот момент считывания и стирания и записи, если все будет одновременно, то в этом уже сама винда разберется, и то что записалось после стирания (смотря как винда решила) встанут в очередь уже на следующем круге.

Win 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.