Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.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
Multithreading 如何在执行循环过程时退出forkIO线程_Multithreading_Haskell - Fatal编程技术网

Multithreading 如何在执行循环过程时退出forkIO线程

Multithreading 如何在执行循环过程时退出forkIO线程,multithreading,haskell,Multithreading,Haskell,我写了一些类似于音乐播放器的东西,却被播放进度条卡住了 在我的程序中,当单击播放按钮时,我使用forkIO来分叉一个控制进度条的线程。但是,分叉线程现在执行一个循环。当我停止当前歌曲或更改歌曲时,如何通知线程终止 例如,我一直在尝试使用iorefvar flag您可以使用IORefs在线程之间进行通信。IORef在分叉线程中引用的内容与在主线程中引用的内容相同 您应该检查以下几点: 分叉线程是否确实有机会测试IORef 您所期望的UI交互真的能从分叉线程中发生吗?许多UI库,包括gtk和Ope

我写了一些类似于音乐播放器的东西,却被播放进度条卡住了

在我的程序中,当单击播放按钮时,我使用forkIO来分叉一个控制进度条的线程。但是,分叉线程现在执行一个循环。当我停止当前歌曲或更改歌曲时,如何通知线程终止

例如,我一直在尝试使用iorefvar


flag您可以使用
IORef
s在线程之间进行通信。
IORef
在分叉线程中引用的内容与在主线程中引用的内容相同

您应该检查以下几点:

  • 分叉线程是否确实有机会测试
    IORef
  • 您所期望的UI交互真的能从分叉线程中发生吗?许多UI库,包括
    gtk
    OpenGL
    ,对线程可以与UI交互有限制
  • 标志设置的时间是否足够长,使分叉线有机会看到它?如果在分叉线程调用
    readIORef
    之前,将标志设置为
    True
    ,然后返回到
    False
    ,则不会检测到停止
解决最后一个问题的一种方法是使用
Integer
而不是
Bool
作为标志

newFlag :: IO (IORef Integer)
newFlag = newIORef 0
该标志的观察者在创建观察者时会记住该标志的值,并在该值变大时停止。当线程可以继续时(该标志尚未升起),此操作将返回
True

这个小示例程序演示了一个与其他线程共享标志的
IORef
。当给定输入
“f”
时,它分叉新线程;当给定输入
“s”
时,它发出停止线程的信号;当给定输入
“q”
时,它退出

main=do
旗手
拉丝旗
返回()
去
线程周期性地执行一些“工作”(需要半秒钟),并在继续之前测试continue条件

thread :: IO Bool -> IO ()
thread continue = go
    where
        go = do
            me <- myThreadId
            putStrLn (show me ++ " Outputting")
            threadDelay 500000
            c <- continue
            if c then go else putStrLn (show me ++ " Stopping") >> return ()
thread::IO Bool->IO()
线程继续=执行
哪里
去做
我返回()
raiseFlag :: IORef Integer -> IO ()
raiseFlag ref = atomicModifyIORef ref (\x -> (x+1,()))
main = do
    flag <- newFlag
    let go = do
        command <- getLine
        case command of
            "f" -> do
                continue <- testFlag flag
                forkIO $ thread continue
                go
            "s" -> do
                raiseFlag flag
                go
            "q" -> do
                raiseFlag flag
                return ()
    go
thread :: IO Bool -> IO ()
thread continue = go
    where
        go = do
            me <- myThreadId
            putStrLn (show me ++ " Outputting")
            threadDelay 500000
            c <- continue
            if c then go else putStrLn (show me ++ " Stopping") >> return ()