Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 499
Dog Avatar asked Dec 20 '22 18:12

Dog


1 Answers

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
like image 50
leftaroundabout Avatar answered Apr 17 '23 07:04

leftaroundabout