Моя основная функция имеет один бесконечный цикл, и я хотел бы выполнить каждый цикл из них каждые 100 миллисекунд. Я знаю, что это делается с помощью параллельного или параллельного метода, но я никогда раньше этого не делал и понятия не имел, с чего начать. Как бы вы реализовали такую функцию?Укажите миллисекунду скорости бесконечного цикла
ответ
Предполагая, что ваше тело цикла занимает незначительное время, просто используйте threadDelay
из Control.Concurrent
:
import Control.Concurrent
main = forever $ do
mainBody
threadDelay (100*1000) -- value in microseconds
Update: Для учета времени вашего тела цикла, используйте:
import Data.Time.Clock
import Control.Concurrent
import Control.Monad
mainBody :: IO()
mainBody = putStrLn "hi"
main = forever $ do
start <- getCurrentTime
mainBody
end <- getCurrentTime
let diff = diffUTCTime end start
usecs = floor (toRational diff * 1000000) :: Int
delay = 100*1000 - usecs
if delay > 0
then threadDelay delay
else return()
Вы можете использовать sleep для приостановки цикла в конце каждой итерации в течение 100 миллисекунд. https://www.haskell.org/hoogle/?q=sleep
Но обратите внимание на предупреждение: _Warning: Эта функция имеет несколько недостатков ..._ Это лучше использовать 'threadDelay' из Control.Concurrent. – ErikR
@ user5402 хотите расширить? – AJFarmar
Извините за поздний ответ. Хорошее наблюдение, я не думал об этом, хотя я не специалист по Haskell @ user5402 –
темы Хаскеля являются легкими, поэтому быстрое решение будет заключаться в вилке на каждом цикле. Таким образом, вы в конечном итоге будете использовать основной поток в качестве менеджера рабочих потоков, который гарантирует, что рабочий будет порожден каждые 100 микронов.
import Control.Concurrent
main =
forever $ do
forkIO $ loopCycle
threadDelay $ 100 * 10^3
В случае, если вы заботитесь об исключениях не заблудиться и получать ререйз в главном потоке вместо этого, я рекомендую взглянуть на the "slave-thread" package. На самом деле, я бы рекомендовал использовать этот пакет вместо forkIO
и братьев по умолчанию, но тогда я автор, поэтому я могу быть субъективным.
Также обратите внимание, что вышеупомянутое решение может вызвать накопление рабочих потоков в случае, если loopCycle
займет более 100 микросов, чтобы выполнить слишком часто. Чтобы защитить от такого сценария, вы можете реализовать стратегию в потоке менеджера, которая позволит ограничить количество активных работников. Ниже показано, как можно было бы реализовать такую стратегию:
-- From the "SafeSemaphore" package
import qualified Control.Concurrent.SSem as Sem
main =
manager 12 (100 * 10^3) $ putStrLn "Implement me!"
manager :: Int -> Int -> IO() -> IO()
manager limit delay worker =
do
sem <- Sem.new limit
forever $ do
forkIO $ Sem.withSem sem $ worker
threadDelay delay
Я проверил библиотеку. Спасибо за вашу идею! –
"реализовать стратегию в потоке менеджера, которая будет гарантировать, что количество активных работников ограничено" как? используя какие функции? некоторые указатели были бы полезны ... –
@WillNess Пожалуйста, просмотрите обновления. –
- 1. Ограничение скорости бесконечного цикла while в Python
- 2. бесконечного цикла
- 3. Java производительность бесконечного цикла
- 4. Почему для бесконечного цикла?
- 5. Java - конец бесконечного цикла
- 6. Код бесконечного цикла
- 7. Рекурсия бесконечного цикла?
- 8. Величина бесконечного цикла
- 9. Сборка бесконечного цикла
- 10. mod_rewrite проблема бесконечного цикла
- 11. Разрыв моего бесконечного цикла
- 12. Замена бесконечного цикла
- 13. Запись бесконечного цикла
- 14. Сборка: Разрыв бесконечного цикла
- 15. Фиксация бесконечного цикла?
- 16. Java проблема бесконечного цикла
- 17. Выход из бесконечного цикла
- 18. Ошибка бесконечного цикла Java
- 19. c Ошибка бесконечного цикла
- 20. Замена для бесконечного цикла
- 21. Не вижу бесконечного цикла
- 22. Завершение бесконечного цикла while
- 23. фиксация непреднамеренного бесконечного цикла
- 24. выйти из бесконечного цикла?
- 25. проблема конкатенации бесконечного цикла
- 26. Bash Программирование бесконечного цикла
- 27. HashMap Итерация бесконечного цикла
- 28. Завершение бесконечного цикла while
- 29. Ошибка бесконечного цикла EditText
- 30. Выход бесконечного цикла
Спасибо за ответ, но тело цикла занимает разное время. Можно занять 80 миллисекунд, а другое может занять 0. Я бы хотел, чтобы они соответствовали всей их длительности. –
Спасибо за обновление :) –