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
Multithreading Haskell线程是否为GC';d如果在MVar/Chan/TQueue读取上无限期阻止?_Multithreading_Haskell - Fatal编程技术网

Multithreading Haskell线程是否为GC';d如果在MVar/Chan/TQueue读取上无限期阻止?

Multithreading Haskell线程是否为GC';d如果在MVar/Chan/TQueue读取上无限期阻止?,multithreading,haskell,Multithreading,Haskell,我有一个线程,它重复地从一个MVar/Chan/TQueue/etc获取信息,然后执行一些处理。如果线程有唯一剩余的对该MVar/Chan/TQueue的引用,并且因此被无限期阻止,那么该线程是否会被GC'd?(无论是MVar、Chan、还是TQueue,这都很重要吗?)我们可以依靠这个GC来实现吗?在什么情况下可能不会发生 如果GC没有发生,或者它被认为太脆弱,那么关闭一个线程的首选方法是什么?这样的无限期读取被阻塞?总之,答案是一个睡眠线程被确定为唯一引用了MVar和TVar(返回Chan,

我有一个线程,它重复地从一个
MVar
/
Chan
/
TQueue
/etc获取信息,然后执行一些处理。如果线程有唯一剩余的对该
MVar
/
Chan
/
TQueue
的引用,并且因此被无限期阻止,那么该线程是否会被GC'd?(无论是
MVar
Chan
、还是
TQueue
,这都很重要吗?)我们可以依靠这个GC来实现吗?在什么情况下可能不会发生


如果GC没有发生,或者它被认为太脆弱,那么关闭一个线程的首选方法是什么?这样的无限期读取被阻塞?

总之,答案是一个睡眠线程被确定为唯一引用了
MVar
TVar
(返回
Chan
TQueue
TMVar
,等等),并且在使用所述引用时被阻止,将抛出异常,如果未捕获,将终止线程。实际上就是这么简单

注意事项如下:

  • 您不知道GC何时运行,也不知道它的攻击性有多大(也许MVar已经升级到了不经常收集的老一代?),因此您不应该假设对象在运行时眼中何时变得不可访问。请注意,对于任何在GC语言中变得不可访问的运行时值,这都是正确的,因此它实际上并不特定于Haskell并发
  • 从理论上讲,很难对对象何时可到达进行推理,尤其是在存在优化的情况下。好吧,很好

因此,使用这些运行时触发的异常来关闭线程(并回收其内存)是完全合理的否则,这将永远处于休眠状态,只要你不关心线程关闭的时间,只想模糊地保证线程可以在运行时需要释放一些内存时关闭。这与你对GC语言中超出范围的任何值所做的推理完全相同ge---在某个时刻,也许很快,也许永远,也许一个小时后,GC将回收这个内存。如果你需要更严格地控制时间等,不要将任务外包给GC。

GHC可以检测到一些死锁,从而向线程抛出一个异常并杀死它。讨论了它什么时候可以和什么时候不能。这很有意义。Ba基于这一点,对于
MVar
读取来说,这听起来像是保证线程在被无限期阻塞时能够GC。那么
TQueue
Chan
呢?
Chan
是嵌套的
MVar
s,而
TQueue
STM
单子中工作,这是一种神奇的功能,几乎可以检测到任何一个线程当前作用域中的潜在死锁(即原子地调用
)。然而,并发性仍然是haskell中最容易出错的主题之一,我建议在实际项目中使用它之前通读一遍。我已经拿到了这本书,并将阅读它。虽然对于
TQueue
,我仍然在寻找我的问题的简单答案。对于
TQueue
,假设生产者线程正在以原子方式执行
(writeTQueue msg)
,并且使用者线程正在执行一个
原子化的readTQueue
。如果生产者获得GC'd,在该
readTQueue
上被阻止的使用者是否有资格获得GC?@pchiusano根据正在运行的代码(以及优化等),可能会发生很多事情。“一般来说,你不知道编译器会有多聪明,所以你不应该依赖死锁检测来正确运行你的程序。”。当一个线程在
重试
并保留对
TVar
的最后一个引用(或者任何使用
TVar
的构建,比如
TQueue
)它接收到一个
blockedDefiniteLyonSTM
。因此,如果消费者持有最后一个引用,它将被中断-但确保所有其他引用都是GCed是真正困难的部分。