【问题标题】:Creating a unique time based ID generator with TMVar使用 TMVar 创建基于时间的唯一 ID 生成器
【发布时间】:2018-01-05 08:18:09
【问题描述】:

我正在制作一个基于时间的唯一 ID 生成器来学习并发 Haskell 中的一些概念。

next 应该返回一个唯一的顺序 POSIX 时间,但这个时间戳不必与我接下来调用的确切时刻相匹配。

这段代码显然不会生成唯一的时间戳,我也不明白为什么:

import Control.Concurrent.Async (mapConcurrently)
import Data.Time.Clock.POSIX    (getPOSIXTime)
import Data.Time                (UTCTime)
import Control.Concurrent.STM   (TMVar, atomically, takeTMVar, putTMVar, newTMVarIO)
import Data.List                (nub)

getTime :: (Integral b, RealFrac a) => a -> IO b
getTime precision =
  round . (* precision) . fromRational . toRational <$> getPOSIXTime

next :: Integral b => TMVar b -> IO b
next s = do
  t <- getTime 1 -- one second precision
  atomically $ do
    v <- takeTMVar s
    let t' = if t == v then t + 1 else t
    putTMVar s t'
    return t'

main = do
  next' <- next <$> newTMVarIO 0
  res <- mapConcurrently id [next' | _ <- [1 .. 100]]
  print $ length $ nub res -- expected 100

【问题讨论】:

    标签: haskell stm


    【解决方案1】:

    假设我们在同一秒内调用next 几次,getTime 1 每次返回 42。

    第一次,t 为 42,v 为 0,t /= v 所以 t' 为 42。

    第二次,t 为 42,v 为 42,t == v 所以 t' 为 43,我们存储 43。

    第三次,t 为 42,v 为 43,t /= v 所以 t' 为 42,我们存储 42。

    第四次,t 为 42,v 为 42,t == v 所以 t' 为 43,我们存储 43。

    看到问题了吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-02
      • 1970-01-01
      • 2017-04-15
      • 2014-04-20
      • 1970-01-01
      • 1970-01-01
      • 2010-09-11
      相关资源
      最近更新 更多