Julia 在模块中的 atexit 行为

Leg*_*tin 5 atexit julia

假设我有一个模块SomeModule.jl

module SomeModule

export use_me

function use_me()
  println("I'm useful!")
end

function call_me_in_the_end()
  println("This is the end")
end

atexit(call_me_in_the_end)

end
Run Code Online (Sandbox Code Playgroud)

main.jl使用这个模块:

import SomeModule: use_me

use_me()
Run Code Online (Sandbox Code Playgroud)

由于传入的函数atexit 是在进程退出时调用的,因此我希望在调用时看到main.jl

I'm useful!
This is the end
Run Code Online (Sandbox Code Playgroud)

但我得到的是:

This is the end
I'm useful!
Run Code Online (Sandbox Code Playgroud)

在第一次通话时,并且仅:

I'm useful!
Run Code Online (Sandbox Code Playgroud)

对于所有后续调用,直到我在SomeModule.jl. 进行更改后,一切都会重复。

我尝试将其带出atexit模块,如下所示:

module SomeModule
  ...
end

import SomeModule: call_me_in_the_end

atexit(call_me_in_the_end)
Run Code Online (Sandbox Code Playgroud)

但结果是一样的。

那么,两个问题:

  1. 为什么call_me_in_the_end只调用一次以及如何修复它?
  2. call_me_in_the_end到底如何才能被调用呢?

Julia 的 macOS x86 版本是 1.7.3

Prz*_*fel 5

该模块在第一次运行后进行编译,因此退出挂钩不会在后续运行中附加。

相反,您应该使用__init__每当加载模块时执行的特殊功能:

module SomeModule

function __init__()
  #this gets executed whenever using SomeModule is called regardless of precompilation
  println("Attaching the hook")
  atexit(call_me_in_the_end)
end

function call_me_in_the_end()
  println("This is the end")
end

end
Run Code Online (Sandbox Code Playgroud)

关于输出顺序,这仅与流缓冲有关,并且在多任务应用程序中经常观察到这种行为。只需在调用之前在代码中的flush(stdout)最后一条语句之后添加即可。printlnexit()