Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Fortran中捕获信号时更改变量值_Fortran_Signals - Fatal编程技术网

在Fortran中捕获信号时更改变量值

在Fortran中捕获信号时更改变量值,fortran,signals,Fortran,Signals,在Fortran上开发程序时,使用了一些迭代过程,我需要手动停止迭代(在不终止程序的情况下退出迭代循环) 我决定向进程发送一个信号。我选择了西格尔姆。我已经检查过,它可以被捕获而不会产生任何意外后果 当收到信号时,标志值改变。在迭代循环中检查该标志,如果该标志为真,则退出。下面给出了此类代码的示例 !file mymod.f90 module mymod use ifport integer*4 :: err integer*4 :: SIGNSET

在Fortran上开发程序时,使用了一些迭代过程,我需要手动停止迭代(在不终止程序的情况下退出迭代循环)

我决定向进程发送一个信号。我选择了西格尔姆。我已经检查过,它可以被捕获而不会产生任何意外后果

当收到信号时,标志值改变。在迭代循环中检查该标志,如果该标志为真,则退出。下面给出了此类代码的示例

!file mymod.f90
module mymod
use ifport
integer*4            :: err
integer*4            :: SIGNSET
integer*4, parameter :: mySignal=14
logical*1            :: toStopIteration

contains
!   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !
    integer*4 function setTrap() result(ret)
    implicit none

    call PXFSTRUCTCREATE('sigset',SIGNSET,err)
    call PXFSIGADDSET(SIGNSET,mySignal,err) !add my signal to the set.

    ret=0; return
    end function setTrap
!   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !
    integer*4 function onTrap(sig_num) result(rcode)
    implicit none
    integer*4 :: sig_num,err

    rcode=0
    select case (sig_num)
        case(mySignal)
            write (*,*) 'Signal occurred. Stop iteration called'
            write (*,*) 'flag: ',toStopIteration
            toStopIteration=.true.
            write (*,*) 'flag: ',toStopIteration
            rcode=1
            return
        case (SIGINT) ; stop
        case (SIGTERM); stop
        case (SIGABRT); stop
    end select

    end function onTrap
!   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !
end module mymod

!file main.f90
program main
use mymod
implicit none
integer*4 :: i,j,N,Niters,sum1

err=setTrap()
err=signal(mySignal, onTrap, -1)

toStopIteration=.false.

open (1,file='output')
write (*,*) 'PID=',getpid()
write (1,*) 'Outside',toStopIteration

N=5000000; Niters=100000

do i = 1,Niters
    if (toStopIteration) then
        toStopIteration=.false.
        exit
    endif

    sum1=0
    do j = 1,N
        sum1=sum1+j
    enddo
    write (1,*) i,toStopIteration,sum1
enddo

write (*,*) 'Procedure was terminated due to signal received. The last iteration was', i
write (*,*) 'Now I will do other job for you.'

stop
end program main
应用程序是用ifort编译的:
ifort-c-O2-traceback
。 当我向进程发送信号时
kill-14 pid
, 我得到终端的输出:

 Signal occurred. Stop iteration called
 flag:  F
 flag:  T
但迭代循环仍在运行,如文件中所述,变量“toStopIteration”等于false

无意中,我发现当使用
-O0-traceback
参数编译时,它运行良好。 为什么会这样?变量“toStopIteration”是否在这种优化级别下成为局部变量?我该怎么做才能使它正常工作

提前谢谢。
MuKeP.

正如Lorri所回答的(不幸的是,这个简洁但正确的答案被错误的评论删除了)-尝试toStopIteration上的volatile属性。这会告诉编译器变量可能会被其他东西重新定义,否则从编译器可见的源代码来看,该变量的值在迭代中似乎无法更改,因此每次迭代都测试它是没有意义的。

非常感谢您的帮助。它解决了我的问题。也许对我来说,更准确地阅读说明书更好:)。对于所有人来说,谁会发现这个问题并需要详细信息。您需要使用
logical*1,volatile::toStopIteration
语句。但正如我正确理解的那样,这是2003年Fortran标准中出现的一个特性。