【问题标题】:Sleep in Fortran在 Fortran 中睡觉
【发布时间】:2011-10-19 09:33:42
【问题描述】:

有谁知道在 Fortran 中睡眠给定毫秒数的方法?我不想使用不可移植的系统调用,所以任何 Fortran 或 C 库固有的东西都是首选。

【问题讨论】:

  • 有一个“睡眠”子程序需要几秒钟作为参数,但我不确定它来自哪里(包装到 C 函数?)。它似乎对我想要的效果很好。我在 PC 上使用 Intel Fortran Compiler 12。
  • 我刚刚遇到了一个 Fortran 程序,该程序使用(非标准)调用系统(char_arg)访问系统而没有 cpu 开销。用 pgf90、ifort 和 gfortran 试了一下,一切都很好。因此,可以执行诸如 call system('sleep '//number_of_seconds_string) 之类的操作来获得睡眠功能。没有机会用其他编译器对此进行测试。
  • 我认为sleep 子程序@BrianTriplett 会谈是一个gnu 扩展,所以我不知道它是否符合便携要求

标签: fortran fortran-iso-c-binding


【解决方案1】:

使用 Fortran ISO C Binding 使用 C 库 sleep 以秒为单位休眠:

   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

【讨论】:

  • 您认为 Intel Fortran 内部提供的“睡眠”功能与您在上面提供的功能基本相同吗?
  • 是的,功能上可能是一样的。 gfortran 中有一个类似的子程序。这是一个可能不属于其他编译器的扩展。
  • 嗨,在 Linux 中我可以使用它,它工作正常。在 Windows 和使用 MinGW 时,编译时抱怨找不到睡眠功能。你知道如何解决这个问题吗?
  • 此解决方案不能跨操作系统移植。 (*nix only,我相信。)@milancurcic 下面的答案应该适用于所有操作系统。
【解决方案2】:

您可以使用 Fortran 标准内部函数来执行此操作,而无需 C 绑定:

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

假设可执行文件是slp:

~$ time slp 1234

real        0m1.237s
user        0m1.233s
sys         0m0.003s 

如果您担心它会在午夜左右中断,请为该程序添加一个特殊情况:)

【讨论】:

  • 这让我想起了。如果您在睡眠期间需要 CPU 时间,则绝对不应使用此方法。我假设您不会长时间等待远程数据。如果你这样做了,你最好使用 shell 包装器,因为上面的例子是 cpu 密集型的。
  • 这个答案肯定比公认的答案更便携。
  • 稍微更便携,但它正忙于等待,而不是正常睡​​眠,因此接受的答案是正确的答案。
【解决方案3】:
      ! 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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多