使用 TMVar 创建基于时间的唯一 ID 生成器
Creating a unique time based ID generator with TMVar
我正在制作一个简单的基于时间的唯一 ID 生成器来学习并发的一些概念 Haskell。
next
应该 return 一个唯一的顺序 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
returns 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。
看到问题了吗?
我正在制作一个简单的基于时间的唯一 ID 生成器来学习并发的一些概念 Haskell。
next
应该 return 一个唯一的顺序 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
returns 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。
看到问题了吗?