Why is reading a constantly changing file twice a second apart giving the same value?

StackOverflow https://stackoverflow.com/questions/21470242

  •  05-10-2022
  •  | 
  •  

Pergunta

I just wrote this one liner in Haskell to see the how much bandwidth I'm using per second:

>>> import Control.Monad (forever)
>>> import Control.Concurrent (threadDelay) -- microseconds; 10^6μs = 1s
>>> let f = "/sys/class/net/wlan0/statistics/rx_bytes" in forever $ readFile f >>= \a -> threadDelay (10^6) >> readFile f >>= \b -> print (read b - read a)
0
0
0
0
0
0
0
0
0

But it always says 0. I ran in parallel an equivalent line of code in Bash, which shows that the file was indeed changing during this time:

$ f=/sys/class/net/wlan0/statistics/rx_bytes; while true; do a=`cat $f`; sleep 1; echo $((`cat $f`-a)); done
98
98
2132
3178
230
306
98
98
729

Why does Haskell not see it changing?

Foi útil?

Solução

readFile is lazy, i.e. it doesn't actually access the data in the file until you evaluate the variable bound to it: in your case, read a. At which time the thread delay has already passed, and you evaluate the file in the same state as b!

Do it this way:

forever $ do
   a <- fmap read $ readFile f
   a `seq` threadDelay (10^6)
   b <- fmap read $ readFile f
   print $ b - a
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top