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