Does anyone know of an way to sleep for a given number of milliseconds in Fortran? I do not want to use non-portable system calls so anything intrinsic to Fortran or C libraries would be preferred.
Asked
Active
Viewed 1.2k times
20
-
There is a 'sleep' subroutine that takes a number of seconds as an argument but I'm not sure where that's coming from (wrapper to C function?). It seems to work fine for what I'm intending. I'm using the Intel Fortran Compiler 12 on a PC. – Brian Triplett Aug 03 '11 at 19:36
-
I just ran across a Fortran program that uses a (non-standard) call system(char_arg) that accesses system with no cpu overhead. Tried it out with pgf90, ifort, and gfortran, all are fine with it. So, one could do something like call system('sleep '//number_of_seconds_string) to obtain a sleep function. Did not have a chance to test this with other compilers. – milancurcic Aug 31 '11 at 20:12
-
I think the `sleep` subroutine @BrianTriplett talks is a gnu extension, so I don't know if it fits the being portable requirement – Manuel Pena May 17 '20 at 00:36
3 Answers
15
Using the Fortran ISO C Binding to use the C library sleep to sleep in units of seconds:
module Fortran_Sleep
use, intrinsic :: iso_c_binding, only: c_int
implicit none
interface
! should be unsigned int ... not available in Fortran
! OK until highest bit gets set.
function FortSleep (seconds) bind ( C, name="sleep" )
import
integer (c_int) :: FortSleep
integer (c_int), intent (in), VALUE :: seconds
end function FortSleep
end interface
end module Fortran_Sleep
program test_Fortran_Sleep
use, intrinsic :: iso_c_binding, only: c_int
use Fortran_Sleep
implicit none
integer (c_int) :: wait_sec, how_long
write (*, '( "Input sleep time: " )', advance='no')
read (*, *) wait_sec
how_long = FortSleep ( wait_sec )
write (*, *) how_long
stop
end program test_Fortran_Sleep

M. S. B.
- 28,968
- 2
- 46
- 73
-
do you think the 'sleep' function provided inside of Intel Fortran is basically doing the same thing you provided above? – Brian Triplett Aug 03 '11 at 19:47
-
Yes, the functionally is probably the same. A similar subroutine is available in gfortran. This is an extension that might not be part of some other compiler. – M. S. B. Aug 03 '11 at 21:07
-
1Hi, in Linux I could use this and it works fine. In Windows and using MinGW, when compiling it complains that it cannot find Sleep function. Do you know how to fix this? – Hossein Talebi Apr 20 '14 at 14:37
-
This solution is not portable across OSes. (*nix only, I believe.) @milancurcic 's answer below should work across all OSes. – zbeekman Aug 06 '18 at 19:32
4
You can use Fortran standard intrinsic functions to do this without C binding:
program sleep
!===============================================================================
implicit none
character(len=100) :: arg ! input argument character string
integer,dimension(8) :: t ! arguments for date_and_time
integer :: s1,s2,ms1,ms2 ! start and end times [ms]
real :: dt ! desired sleep interval [ms]
!===============================================================================
! Get start time:
call date_and_time(values=t)
ms1=(t(5)*3600+t(6)*60+t(7))*1000+t(8)
! Get the command argument, e.g. sleep time in milliseconds:
call get_command_argument(number=1,value=arg)
read(unit=arg,fmt=*)dt
do ! check time:
call date_and_time(values=t)
ms2=(t(5)*3600+t(6)*60+t(7))*1000+t(8)
if(ms2-ms1>=dt)exit
enddo
!===============================================================================
endprogram sleep
Assuming the executable is slp:
~$ time slp 1234
real 0m1.237s
user 0m1.233s
sys 0m0.003s
Add a special case to this program if you are worried it will break around midnight :)

milancurcic
- 6,202
- 2
- 34
- 47
-
4Which reminds me. This approach should definitely not be used if you need cpu time during sleep period. I assumed you do not this for long waits for remote data. If you do, you are far better off using a shell wrapper, because example above is cpu intensive. – milancurcic Aug 13 '11 at 14:43
-
-
4It is *slightly* more portable, but it is busy waiting, not proper sleeping, so the accepted answer is the right one to be accepted. – Vladimir F Героям слава Aug 20 '18 at 07:11
-
-1
! This is another option of making your fortran code to wait for x seconds
Integer :: iStart, iNew
Real*8 :: rWait, rDT
! rWait: seconds that you want to wait for; you can also set this as an (IN)
! variable if this code goes into a subroutine that is developed to be called
! from any part of the program.
rWait = 1.d0; rDT = 0.d0
call system_clock (iStart)
do while (rDT <= rWait)
call system_clock (iNew)
rDT = floatj (iNew - iStart) / 10000.d0
enddo

George
- 1
-
2system_clock is still non-portable. It may behave differently on different systems/different compilers. [Check out this answer already.](https://stackoverflow.com/questions/6878246/fortran-intrinsic-timing-routines-which-is-better-cpu-time-or-system-clock) – Dan Sp. Aug 19 '18 at 20:44
-
1It is portable, but one has to query the clock rate and use the value one gets. Also, this is just *busy wating* https://en.wikipedia.org/wiki/Busy_waiting, not proper sleeping. – Vladimir F Героям слава Aug 20 '18 at 07:09