繁体   English   中英

使用TMVar创建唯一的基于时间的ID生成器

[英]Creating a unique time based ID generator with TMVar

我正在制作一个基于天真的时间的唯一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

假设我们在同一秒内调用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。

看到问题了吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM