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

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

  •  05-10-2022
  •  | 
  •  

سؤال

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?

هل كانت مفيدة؟

المحلول

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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top