Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ThreadDelay Problem in Haskell (GHC) on Ubuntu

I noticed odd behavior with the threadDelay function in GHC.Conc on some of my machines. The following program:

main = do print "start"
          threadDelay (1000 * 1000)
          print "done"

takes 1 second to run, as expected. On the other hand, this program:

{-# LANGUAGE BangPatterns #-}
import Control.Concurrent

main = do print "start"
          loop 1000
          print "done"
  where loop :: Int -> IO ()
        loop !n =
          if n == 0 
          then return ()
          else do threadDelay 1000
                  loop (n-1)

takes about 10 seconds to run on two of my machines, though on other machines it takes about 1 second, as expected. (I compiled both of the above programs with the '-threaded' flag.) Here is a screen shot from Threadscope showing that there is activity only once every 10 milliseconds: Screenshot of ThreadScope showing that threadDelay of 1 millisecond sleeps for 10 milliseconds.

On the other hand, here is a screenshot from ThreadScope from one of my machines on which the program takes 1 second total: Screenshot of ThreadScope showing that threadDelay of 1 millisecond sleeps for about 1 milliseconds.

A similar C program:

#include <unistd.h>
#include <stdio.h>

int main() {
  int i; 
  for (i=1; i < 1000; i++) {
    printf("%i\n",i);
    usleep(1000);
  }
  return 0;
}

does the right thing, i.e. running 'time ./a.out' gives output like:

1
2
...
999

real 0m1.080s
user 0m0.000s
sys  0m0.020s

Has anyone encountered this problem before, and if so, how can this be fixed? I am running ghc 7.2.1 for Linux(x86_64) on all of my machines and am running various versions of Ubuntu. It works badly on Ubuntu 10.04.2, but fine on 11.04.

like image 203
Andreas Avatar asked Sep 15 '11 18:09

Andreas


1 Answers

threadDelay is not an accurate timer. It promises that your thread will sleep for at least as long as its argument says it should, but it doesn't promise anything more than that. If you want something to happen periodically, you will have to use something else. (I'm not sure what, but possibly Unix' realtime alarm signal would work for you.)

like image 137
Daniel Wagner Avatar answered Sep 29 '22 14:09

Daniel Wagner