Unique timestamp identifier for multiple threads in Haskell

I have many thread processing events. I want to assign a nanosecond timestamp for each event. However, this must be a unique identifier. Thus, in the odd case, when two events arrive so that they will be assigned the same timestamp, I want one of them to be increased by one nanosecond. Given that real accuracy is not at the nanosecond level, this is good as far as the nature of the system’s temporary system.

In one thread, this is a trivial problem. But after a few threads, it gets more complicated. Performance is absolutely important, so the idea of ​​naive synchronization on a typical type of type of identifier generator seems to block too much.

Is there any approach that resolves this with minimal or no blockage?

+6
source share
5 answers

You can use atomicModifyIORef to implement an atomic counter. With the GHC, it is implemented using atomic operations, not blocking.

 import Data.IORef import System.IO.Unsafe counter :: IO Int counter = unsafePerformIO $ newIORef 0 getUnique :: IO Int getUnique = atomicModifyIORef counter $ \x -> let y = x + 1 in (y, y) 
+1
source

Why not separate the problems of creating timestamps and the unique generation of identifiers? For example, there is a standard Data.Unique module that provides a global supply of unique values ​​in IO and should be fast enough for most purposes, Or, if you need something more interesting, the concurrent-supply package offers a high-performance parallel unique ID source with a clean interface .

However, you could use a POSIX monotone watch for this purpose, using, for example, clock :

 import Control.Monad import qualified System.Posix.Clock as Clock main :: IO () main = replicateM_ 100 $ do time <- Clock.getTime Clock.Monotonic print (Clock.sec time, Clock.nsec time) 
+2
source

Could you use two pieces of information as a unique identifier? If so, give each thread a unique identifier and record for each event a nanosecond time stamp and a thread identifier that assigns a time stamp. Then the problem boils down to what you would do in a single-threaded package to guarantee the uniqueness of timestamps. And without synchronization at all after initialization.

+2
source

In C languages, we usually do this with an atomic counter - no lock is required. If you also need a timestamp, this will be a separate value. I am not sure about Haskell because I am not writing with it (interesting as it may be).

0
source

Source: https://habr.com/ru/post/907139/


All Articles