Fortran 调用睡眠不会阻止程序
Fortran call to sleep does not block program
我有最基本的 Fortran 程序:
program sleep
print*, "Sleeping"
call sleep(30)
print*, "Done"
end program sleep
我用 gfortran sleep.f90
(版本 9.3.0)编译。根据我从 sleep
文档中了解到的情况,该程序应该休眠 30 秒,即我应该期望在“休眠”30 秒后看到“完成”打印出来。这不会发生:我看到两个打印语句同时出现,表明 call sleep(30)
不会以任何方式阻止我的程序。做 call sleep(10000)
没有任何区别。我正在为 Linux (WSL Ubuntu 20.04) 在 Windows 子系统上编译和 运行 这个程序。
所以这个问题是通过@roygvib 在评论中建议的组合解决方案解决的。主要问题是 WSL (Ubuntu 20.04) 环境中的 sleep
已损坏。第一步是将损坏的 /usr/bin/sleep
替换为 this Python script:
#!/usr/bin/env python3
import sys
import time
time.sleep(int(sys.argv[1]))
然后,修改 Fortran 程序以 system
调用这个新的 sleep
可执行文件:
program sleep
print*, "Sleeping"
call system("sleep 30")
print*, "Done"
end program sleep
在 WSL 的下一次更新之前,必须执行此 hack。
sleep
过程不是 Fortran 标准和 non-portable 的一部分。这是一个可能适用于任何 standard-compliant Fortran 编译器的所有系统的解决方案:
module sleep_mod
use, intrinsic :: iso_fortran_env, only: IK => int64, RK => real64, output_unit
implicit none
contains
subroutine sleep(seconds)
implicit none
real(RK), intent(in) :: seconds ! sleep time
integer(IK) :: countOld, countNew, countMax
real(RK) :: countRate
call system_clock( count=countOld, count_rate=countRate, count_max=countMax )
if (countOld==-huge(0_IK) .or. nint(countRate)==0_IK .or. countMax==0_IK) then
write(output_unit,"(A)") "Error occurred. There is no processor clock."
error stop
end if
countRate = 1._RK / countRate
do
call system_clock( count=countNew )
if (countNew==countMax) then
write(output_unit,"(A)") "Error occurred. Maximum processor clock count reached."
error stop
end if
if ( real(countNew-countOld,kind=RK) * countRate > seconds ) exit
cycle
end do
end subroutine sleep
end module sleep_mod
program main
use sleep_mod, only: output_unit, sleep, RK
implicit none
write(output_unit,"(A)") "Sleep for 5 second."
call execute_command_line(" ") ! flush stdout
call sleep(seconds = 5._RK)
write(output_unit,"(A)") "Wake up."
end program main
您可以在这里在线测试:https://www.tutorialspoint.com/compile_fortran_online.php
我有最基本的 Fortran 程序:
program sleep
print*, "Sleeping"
call sleep(30)
print*, "Done"
end program sleep
我用 gfortran sleep.f90
(版本 9.3.0)编译。根据我从 sleep
文档中了解到的情况,该程序应该休眠 30 秒,即我应该期望在“休眠”30 秒后看到“完成”打印出来。这不会发生:我看到两个打印语句同时出现,表明 call sleep(30)
不会以任何方式阻止我的程序。做 call sleep(10000)
没有任何区别。我正在为 Linux (WSL Ubuntu 20.04) 在 Windows 子系统上编译和 运行 这个程序。
所以这个问题是通过@roygvib 在评论中建议的组合解决方案解决的。主要问题是 WSL (Ubuntu 20.04) 环境中的 sleep
已损坏。第一步是将损坏的 /usr/bin/sleep
替换为 this Python script:
#!/usr/bin/env python3
import sys
import time
time.sleep(int(sys.argv[1]))
然后,修改 Fortran 程序以 system
调用这个新的 sleep
可执行文件:
program sleep
print*, "Sleeping"
call system("sleep 30")
print*, "Done"
end program sleep
在 WSL 的下一次更新之前,必须执行此 hack。
sleep
过程不是 Fortran 标准和 non-portable 的一部分。这是一个可能适用于任何 standard-compliant Fortran 编译器的所有系统的解决方案:
module sleep_mod
use, intrinsic :: iso_fortran_env, only: IK => int64, RK => real64, output_unit
implicit none
contains
subroutine sleep(seconds)
implicit none
real(RK), intent(in) :: seconds ! sleep time
integer(IK) :: countOld, countNew, countMax
real(RK) :: countRate
call system_clock( count=countOld, count_rate=countRate, count_max=countMax )
if (countOld==-huge(0_IK) .or. nint(countRate)==0_IK .or. countMax==0_IK) then
write(output_unit,"(A)") "Error occurred. There is no processor clock."
error stop
end if
countRate = 1._RK / countRate
do
call system_clock( count=countNew )
if (countNew==countMax) then
write(output_unit,"(A)") "Error occurred. Maximum processor clock count reached."
error stop
end if
if ( real(countNew-countOld,kind=RK) * countRate > seconds ) exit
cycle
end do
end subroutine sleep
end module sleep_mod
program main
use sleep_mod, only: output_unit, sleep, RK
implicit none
write(output_unit,"(A)") "Sleep for 5 second."
call execute_command_line(" ") ! flush stdout
call sleep(seconds = 5._RK)
write(output_unit,"(A)") "Wake up."
end program main
您可以在这里在线测试:https://www.tutorialspoint.com/compile_fortran_online.php