Тема: AHK: Подпрограммы
Можно ли сделать так, чтобы в одной программе работало 2 подпрограммы не зависящие друг от друга? Тоесть как бы взять и два скрипта в один слить, но без последствий.
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Можно ли сделать так, чтобы в одной программе работало 2 подпрограммы не зависящие друг от друга? Тоесть как бы взять и два скрипта в один слить, но без последствий.
Можно ли сделать так, чтобы в одной программе работало 2 подпрограммы не зависящие друг от друга? Тоесть как бы взять и два скрипта в один слить, но без последствий.
Нет, AHK не поддерживает многопоточность в полном объёме.
Можно использовать SetTimer (получается подобие многопоточности).
Пример:
SetTimer,Программа1,10 ; Число 10 это периодичность выполнения в милисекундах
SetTimer,Программа2,10
Программа1:
{
Код программы.
}
return
Программа2:
{
Код второй программы.
}
return
Но нужно учитывать чтобы переменные и горячие клавиши несовпадали в разных програмах и изначальные условия должны быть совместимыми (CoordMode, SendMode, SetFormat, и т.д.).
Alectric, в твоём примере пока подпрограмма одногого таймера полностью не выполнится, второй не запустится.
CoordMode, ToolTip
SetTimer,Программа1,10 ; Число 10 это периодичность выполнения в милисекундах
SetTimer,Программа2,10
Программа1:
{
Loop
{
ToolTip % "Первый Таймер "A_Index, 300, 300, 1
Sleep, 100
}
}
return
Программа2:
{
Loop
{
ToolTip % "Второй Таймер "A_Index, 420, 300, 2
Sleep, 100
}
}
return
(получается подобие многопоточности).
Помоему это лучше чем так:
loop
{
sleep,10
Код программы 1.
sleep,10
Код программы 2.
}
return
Alectric, в твоём примере пока подпрограмма одногого таймера полностью не выполнится, второй не запустится.
А зачем вам непрерывный цикл Loop, если SetTimer уже работает как цикл?
CoordMode, ToolTip
SetTimer,Программа1,100 ; Число 10 это периодичность выполнения в милисекундах
SetTimer,Программа2,10
loop
{
ToolTip % "Основной Таймер "a_index, 300, 300, 1
sleep,1000
}
return
Программа1:
a+=1
ToolTip % "Первый Таймер "a, 420, 320, 2
return
Программа2:
b+=1
ToolTip % "Второй Таймер "b, 540, 340, 3
return
или так:
#persistent
CoordMode, ToolTip
SetTimer,Программа1,100 ; Число 10 это периодичность выполнения в милисекундах
SetTimer,Программа2,10
Программа1:
a+=1
ToolTip % "Первый Таймер "a, 420, 320, 2
return
Программа2:
b+=1
ToolTip % "Второй Таймер "b, 540, 340, 3
return
Или так:
CoordMode, ToolTip
SetTimer,Программа1,100 ; Число 10 это периодичность выполнения в милисекундах
SetTimer,Программа2,10
F1::
c+=1
ToolTip % "Основной Таймер "c, 300, 300, 1
return
Программа1:
a+=1
ToolTip % "Первый Таймер "a, 420, 320, 2
return
Программа2:
b+=1
ToolTip % "Второй Таймер "b, 540, 340, 3
return
Помоему это лучше чем так:
loop { sleep,10 Код программы 1. sleep,10 Код программы 2. } return
Очевидно, что хуже. А Sleep'ы в один квант для того, чтоб процессор отдохнул? Параллельность можно обеспечить только машинным кодом или дополнительным процессом.
Ну я же уже писал: получается "подобие" многопоточности!
А не "идеальная" многопоточность.
Ну я же уже писал: получается "подобие" многопоточности!
А не "идеальная" многопоточность.
Если бы вы ещё определение "подобия многопоточности" дали... Для справки отрывок из педивикии:
Многопото́чность — свойство платформы (например, операционной системы, виртуальной машины и т. д.) или приложения, состоящее в том, что процесс, порождённый в операционной системе, может состоять из нескольких потоков, выполняющихся «параллельно», то есть без предписанного порядка во времени.
Запустите скрипт из 6го поста и Вы уидете что "Второй таймер" выполняется каждые 10 милисекунд.
А если
пока подпрограмма одногого таймера полностью не выполнится, второй не запустится.
"Второй таймер" выполнялся бы дольше, тоесть 100+10= через 110 милисекунд.
Тоесть, я так понял, что Settimer заставляет скрипт выполнять поочереди команды, то с первого таймера, то со второго, и получается "подобие многопоточности".
"Второй таймер" выполнялся бы дольше, тоесть 100+10= через 110 милисекунд.
А разве на подпрограмму первого таймера
Программа1:
a+=1
ToolTip % "Первый Таймер "a, 420, 320, 2
return
требуется 110 милисекунд? Просто он запускается раз в 100ms, его подпрограмма выполняется гораздо быстрее и даёт возможность запуститься следующему таймеру.
Запустите скрипт из 6го поста и Вы уидете что "Второй таймер" выполняется каждые 10 милисекунд.
А еслипока подпрограмма одногого таймера полностью не выполнится, второй не запустится.
"Второй таймер" выполнялся бы дольше, тоесть 100+10= через 110 милисекунд.
Тоесть, я так понял, что Settimer заставляет скрипт выполнять поочереди команды, то с первого таймера, то со второго, и получается "подобие многопоточности".
Замечательно, а теперь давайте расширим набор тестов с одного до ~десятка. Исправляем ваш вышеупомянутый скрипт из шестого поста:
CoordMode, ToolTip
SetTimer sub1, 100
SetTimer sub2, 10
time := a_tickcount
loop 10
{
ToolTip % "Основной Таймер "a_index, 300, 300, 1 ;%
sleep 1000
}
SetTimer sub1, off
SetTimer sub2, off
ToolTip % "Итоговое время "(a_tickcount-time), 660, 360, 4 ;%
return
sub1:
;SleepQuantum(1)
;Sleep 1
a++
ToolTip % "Первый Таймер "a, 420, 320, 2 ;%
return
sub2:
;SleepQuantum(1)
;Sleep 1
b++
ToolTip % "Второй Таймер "b, 540, 340, 3 ;%
return
SleepQuantum(n)
{
loop %n%
Sleep 1
return
}
Esc::
ExitApp
return
Тут мы вместо бесконечного цикла, обеспечивавшего нас быстро бегущими циферками, имеем конечный цикл, который должен длиться 10 секунд(10000 миллисекунд). Далее мы засекаем время выполнения этого цикла и отображаем его в четвёртом tooltip'е. Введена функция SleepQuantum(n), которая пропускает n, выделенных ей, квантов процессорного времени. Для проверки полученных данных все тесты стоит повторять трижды, при этом нужно завершить все приложения, способные смазать результаты эксперимента.
Итак, приступим:
1) Какие числа мы ожидаем получить в этих четырёх "тултипах"?
2) Насколько сильно реальные цифры отличаются от расчётных?
Теперь раскомментировать строчки ;SleepQuantum(1) в обеих подпрограммах и провести тесты для значений 1, 2, 3, 5, 10.
3) Почесать затылок и попытаться понять, что за байдень происходит во время выполнения скрипта.
Теперь закомментировать строчки SleepQuantum(*) в обеих подпрограммах и раскомментировать ;Sleep 1. Провести тесты для значений 10, 20, 30, 50, 100.
4) Выявить зависимость между полученными на этом шаге и шаге 3 данными.
5) Придумать тест, который подтвердит или опровергнет тезис "пока подпрограмма одногого таймера полностью не выполнится, второй не запустится". Провести этот тест.
5) Придумать тест, который подтвердит или опровергнет тезис "пока подпрограмма одногого таймера полностью не выполнится, второй не запустится". Провести этот тест.
Насколько я себе представляю, "подпрограмма второго таймера прерывает подпрограмму первого таймера; пока подпрограмма второго полностью не выполнится, подпрограмма первого не продолжится".
CoordMode, ToolTip
SetTimer,Программа1,-1
SetTimer,Программа2,-1
Программа1:
ToolTip Первый Таймер 1
Sleep, 300
ToolTip Первый Таймер 2
Sleep, 300
ToolTip Первый Таймер 3
Sleep, 300
ToolTip Первый Таймер 4
Sleep, 300
ToolTip Первый Таймер 5
Sleep, 300
Return
Программа2:
ToolTip Второй Таймер 1
Sleep, 300
ToolTip Второй Таймер 2
Sleep, 300
ToolTip Второй Таймер 3
Sleep, 300
ToolTip Второй Таймер 4
Sleep, 300
ToolTip Второй Таймер 5
Sleep, 300
return
Запустите этот скрипт в этом виде и понаблюдайте в течении минуты:
CoordMode, ToolTip
SetTimer,Программа1,10
SetTimer,Программа2,10
Программа1:
ToolTip Первый Таймер 1,0,100,1
Sleep, 300
ToolTip Первый Таймер 2,0,100,1
Sleep, 300
ToolTip Первый Таймер 3,0,100,1
Sleep, 300
ToolTip Первый Таймер 4,0,100,1
Sleep, 300
ToolTip Первый Таймер 5,0,100,1
Sleep, 300
Return
Программа2:
ToolTip Второй Таймер 1,0,120,2
Sleep, 300
ToolTip Второй Таймер 2,0,120,2
Sleep, 300
ToolTip Второй Таймер 3,0,120,2
Sleep, 300
ToolTip Второй Таймер 4,0,120,2
Sleep, 300
ToolTip Второй Таймер 5,0,120,2
Sleep, 300
return
Программа3:
ToolTip Третий Таймер 1,0,140,3
Sleep, 300
ToolTip Третий Таймер 2,0,140,3
Sleep, 300
ToolTip Третий Таймер 3,0,140,3
Sleep, 300
ToolTip Третий Таймер 4,0,140,3
Sleep, 300
ToolTip Третий Таймер 5,0,140,3
Sleep, 300
return
Выглядит странно.:/
Получается такая картина:
1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
Тоесть у таймеров поочереди меняется приоритет.
Вы имеето ввиду что скрипт получится неточным по времени.
Тем неменее он будет отрабатывать полностью если его не останавливать цыклами которые не ограничены Break или количеством повторов.
Помоему это мелоч, которую можно незаметить при обыденном использовании скриптов которые обычно выполняются при SetBatchLines,-1 и минимальных sleep'ах.
Ну а если нужна точность по времени, то можно воспользоватся встроенными переменными (A_MSec, A_Sec, A_Min, A_Hour, и т.д.)
Вы имеето ввиду что скрипт получится неточным по времени.
Тем неменее он будет отрабатывать полностью если его не останавливать цыклами которые не ограничены Break или количеством повторов.
Т.е. если цель скрипта висеть в бесконечном цикле и выполнять подпрограммы в псевдослучайном порядке, то ваш метод работает очень неплохо. Рекомендую переключиться с AHK на Malbolge.
Помоему это мелоч, которую можно незаметить при обыденном использовании скриптов которые обычно выполняются при SetBatchLines,-1 и минимальных sleep'ах.
Из-за этой мелочи программа может неверно выполнится. А ещё в "обыденном использовании скриптов" не нужна многопоточность.
Ну а если нужна точность по времени, то можно воспользоватся встроенными переменными (A_MSec, A_Sec, A_Min, A_Hour, и т.д.)
Шутка?
Насколько я себе представляю, "подпрограмма второго таймера прерывает подпрограмму первого таймера; пока подпрограмма второго полностью не выполнится, подпрограмма первого не продолжится".
Я рассчитывал, что к этому выводу сможет придти Alectric, но судя по его посту:
Запустите этот скрипт в этом виде и понаблюдайте в течении минуты:
...
Выглядит странно...
религия ему не позволяет даже прочитать верный ответ. Кстати в этом скрипте первой метке управление передаётся без таймера, а третья метка оставлена в знак протеста против Бритвы Оккама .
Необращайте на меня внимания, я просто запутался в терминах.
А при чем тут религия? Просто до меня недоходило...
А при чем тут религия?
Это фразеологизм. Примеры:
В: Сколько будет 3456*123?
О: А калькулятор использовать религия не позволяет?
В: В каком году умер Пушкин?
О: погуглить религия не позволяет?
Кстати, редактирование сделано не для удаления частей своего сообщения, а для внесения дополнений и исправления неточностей. Это очень важно, поскольку на удалённый текст кто-то может ответить.
Ясно...
Спасибо за ответы...
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться