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