Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如何使用System.Cron.Schedule处理长时间运行的作业?_Haskell_Job Scheduling - Fatal编程技术网

Haskell 如何使用System.Cron.Schedule处理长时间运行的作业?

Haskell 如何使用System.Cron.Schedule处理长时间运行的作业?,haskell,job-scheduling,Haskell,Job Scheduling,我想学哈斯克尔。首先,我希望编写一个守护进程,定期为我运行备份作业 我正在使用来为我做调度,并运行可执行文件来做备份 由于这是一个备份作业,运行可能需要一段日志时间,为了防止在上一个计划备份尚未完成时运行下一个计划备份,我希望确保只能运行该作业的一个实例。如何防止长时间运行的作业再次运行 作为一个简化的示例,我如何使以下内容在现有作业完成之前不会每分钟生成另一个作业 main :: IO () main = do tids <- execSchedule $ do

我想学哈斯克尔。首先,我希望编写一个守护进程,定期为我运行备份作业

我正在使用来为我做调度,并运行可执行文件来做备份

由于这是一个备份作业,运行可能需要一段日志时间,为了防止在上一个计划备份尚未完成时运行下一个计划备份,我希望确保只能运行该作业的一个实例。如何防止长时间运行的作业再次运行

作为一个简化的示例,我如何使以下内容在现有作业完成之前不会每分钟生成另一个作业

main :: IO ()
main = do
       tids <- execSchedule $ do
           addJob doBackup "* * * * *"
       print tids

doBackup :: IO ()
doBackup = do
    putStrLn "Backing up system..."
    threadDelay 70000000
    putStrLn "Backup finished"
main::IO()
main=do

tids以下是@Alec建议的实施情况。这将创建一个
MVar()
(基本上是一个信号量),然后每次作业运行时,它都会在继续之前检查
MVar
是否空闲,否则它就会死亡

import Control.Concurrent.MVar
import Control.Monad

main :: IO ()
main = do sem <- newMVar () -- starts off not taken
          tids <- execSchedule $ addJob (doBackup sem) "* * * * *" -- do x = x
          print tids
          forever $ threadDelay maxBound
       -- all threads exit when main exits. ^ stops that from happening
       -- Control.Monad.forever x = let loop = x >> loop in loop
       -- don't do forever $ return () unless you want a CPU-nomming busyloop


doBackup :: MVar () -> IO ()
doBackup sem = do res <- tryTakeMVar sem
               -- gives Nothing if the sem is taken and Just () if it isn't
               -- you DON'T want takeMVar, since that'll block until sem is
               -- free, essentially queueing the jobs up instead of
               -- canceling the ones that run too early.
                  case res of
                       Nothing -> return () -- already taken? do nothing
                       Just () -> do putStrLn "Backing up system..."
                                     threadDelay 70000000
                                     putStrLn "Backup finished"
                                     putMVar sem () -- release the lock
import Control.Concurrent.MVar
进口管制
main::IO()
main=在循环中执行sem循环
--除非您想要一个CPU命名的busylop,否则不要永远使用$return()
doBackup::MVar()->IO()

doBackup sem=do res您可能想发布一些代码-解决这一问题实际上取决于您到目前为止掌握了什么。浏览一下
System.Cron.Schedule
文档,您可能会在
IO
monad(或者是
MonadIO
)中做很多工作。您可以使用来阻止作业在上一个作业完成之前启动。在实际代码中,我建议将此功能抽象到它自己的单元中,例如
oneAtATime::MVar()->IO()->IO()