【问题标题】:Haskell Concurrent.Channel: What is difference between this two codes?Haskell Concurrent.Channel:这两个代码有什么区别?
【发布时间】:2018-04-16 23:06:57
【问题描述】:

为什么是这个代码

import Control.Monad
import Control.Concurrent
import Control.Concurrent.STM
import Control.Concurrent.STM.TChan

main = do
  ch <- newTChanIO
  forkIO $ consumer ch 0
  forkIO $ consumer ch 1
  ----------------------
  forkIO $ producer ch
  ----------------------
  return ()


producer ch = loop 0
  where
    loop n = do
      atomically $ writeTChan ch n
      threadDelay (10^5 :: Int)
      loop (n+1)


consumer ch n = forever $ do
  v <- atomically $ readTChan ch
  print (n, v)

行为方式与

不同
import Control.Monad
import Control.Concurrent
import Control.Concurrent.STM
import Control.Concurrent.STM.TChan

main = do
  ch <- newTChanIO
  forkIO $ consumer ch 0
  forkIO $ consumer ch 1
  ----------------------
  producer ch
  ----------------------
  return ()


producer ch = loop 0
  where
    loop n = do
      atomically $ writeTChan ch n
      threadDelay (10^5 :: Int)
      loop (n+1)


consumer ch n = forever $ do
  v <- atomically $ readTChan ch
  print (n, v)

后面代码的输出是

(0,0)
(1,1)
(1,2)
(1,3)
(1,4)
(0,5)
(0,6)
(1,7)
...

但是,前者的输出只有

(0,0)

我打算让producer 无限期地向通道队列ch 添加一个值,而consumer 无限期地从ch 中获取一个值。

后一个代码和我的意图一样,但前一个没有。

在事件日志 (ghc-events) 中,阻塞发生在 producer 线程中的 MVar 上

4775372: cap 0: stopping thread 8 (blocked on an MVar)

为什么以前的代码(forkIO $ producer ch)不能无限期运行。

【问题讨论】:

    标签: haskell concurrency channel


    【解决方案1】:

    http://hackage.haskell.org/package/base-4.10.0.0/docs/Control-Concurrent.html#g:12:

    在独立的 GHC 程序中,只有主线程需要终止才能终止进程。因此,所有其他分叉线程将与主线程同时终止(这种行为的术语是“守护线程”)。

    如果您希望程序在退出之前等待子线程完成,您需要自己编程。

    http://chimera.labs.oreilly.com/books/1230000000929/ch07.html#sec_reminders:

    [...] 这告诉了我们关于 Haskell 中线程如何工作的一些重要信息:main 返回时,即使还有其他线程仍在运行,程序也会终止。其他线程在main 返回后停止运行并不再存在。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-06
      • 2020-03-29
      • 2012-01-30
      • 1970-01-01
      相关资源
      最近更新 更多