原因是当GHCi中的函数退出时,它产生的线程不会自动终止,即使通过代码重新加载仍然存在.重新启动GHCi解决了这个问题,但是由于我的应用程序需要一段时间才能加载,所以如果有可能(甚至是黑客)的解决方法,这将是巨大的.
解决方法
此外,您无法可靠地猜测使用forkIO产生的线程属于您的GHCi会话(所有评估通常在forkIO中进行沙盒),底层的yesod应用程序或线程RTS(至少有一个对forkIO的调用),这基本上确保了所有事件管理器都关闭).目前,这并不是太糟糕了,因为GHCi运行在主线程中,如果关闭,IO管理器将重新启动,但在将来的版本中可能会发生更改.
那么为什么线程甚至在终止时收集? hs_exit()
.本质上,它调用ioManagerDie()(kill all event managers)和exitScheduler(..)(参见scheduler,基本上是kills all threads.这些函数都没有一个适当的FFI包装器.
在调用hs_exit()时,Haskell世界的主要功能已经完成.因为这些函数中没有一个在GHC *模块中具有适当的等效项,所以不能直接在Haskell中调用它们,因此不能在GHCi中调用它们,因为没有适当的:#命令.
所以总而言之,你不能.如果要添加一个命令来重新启动GHCi中的调度程序,这将很容易.但是考虑到调度程序在hs_init()中启动并在RTS model中的hs_exit()中停止,我怀疑这将是一个容易的扩展.
根据你想做什么,你可以作弊.您可以编写自己的forkIOMem,它将ThreadId存储在全局MVar中,并替换源中的所有forkIO.这可能非常麻烦,特别是如果您正在使用图书馆,因为您需要确保将forkIO替换到任何地方.
当然,您可以使用基础包,但是这可能是疯狂的(尽管如此),更改forkIO,并将killAllforkIO添加到Control.Concurrent. (我已经说过这可能是疯狂的吧?)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。