Julia 语言 - @async 任务中的状态 :: 当前目录

2024-01-04

我注意到(阅读:捕获了生产错误)Julia 中的不同任务 - 没有自己的工作目录,但当前目录 - 是共享的。我意识到在操作系统级别这是显而易见的(一个进程有一个工作目录)。

我的问题是第一 - 是否有任何其他明显或不太明显的全局状态我应该注意(显然是环境变量或任何全局变量)。

其次 - 如果这应该有更多记录,或者通过任务抽象来避免, - 抽象中的“任务”,它可以(理论上)拥有自己的语义,例如移回工作目录。

我们通过从代码中删除任何“cd()”调用解决了产品错误,重点是 - 具有闭包抽象的 cd() 给我们一种错觉,认为这可能可以安全使用。

ie:

cd("some_dir") do
  # stuff
end

我们已经有这样的代码在工作Mux https://github.com/JuliaWeb/Mux.jl端点。

我对这个问题的最小再现是

function runme(path)
    mkpath(path)
    abs_path = realpath(path)
    return t = @async begin
        cd(abs_path) do
            sleep(1)
            println(path,"::",(pwd()|>splitdir)[2])
        end
    end
end

runme("a")
runme("b")

输出:(显然)

a::b
b::b

编辑:(摘要)-虽然这几乎不是一个问题-这应该是可搜索和记录的(因为它是同步错误的可能来源)。

与全局变量的区别(关于“cd()”的状态)——可以使用闭包在闭包中捕获变量let声明,而当前目录则不能。虽然这甚至不是特定于编程语言的(而是操作系统进程问题) - 我认为语法确实给出了局部性的错觉(类似于 python 'with' 块或许多其他设备)。

因此,底线是“cd”抽象不应在任何生产实用程序中使用,除非有一天有一种方法可以设置一个处理程序以“切换回”任务/块/闭包(类似于finally以某种方式阻止)


我没有明确了解内部结构或特定实现,这是我个人的有根据的猜测,很高兴由实际的 julia 开发人员纠正,但我认为任务本身并不是共享“当前目录”的情况,但是他们更普遍地共享“状态”。您的示例将与全局变量的行为方式相同:

# in testscript.jl
var = 0;

function runme(val)
    global var = val+1;
    return t = @async begin
      sleep(1)
      println(val,"::",var);
    end
end

runme(1) 
runme(3) 
# in the REPL session
julia> include("testo.jl");
  1::4
  3::4

然而,(全局)状态的共享是一个功能,而不是一个错误。这与流程(这是 Julia 实现真正并行性的方式),它们不共享状态,因此工作人员之间的所有通信都需要通过套接字完成。

虽然人们确实需要小心这一点,但它也可能非常有用和必要。任务(或协程)不用于实现这方面的并行性或限制。它们是“协作多任务处理的一种形式”,即一种在同一线程上实现多个运行操作的方法;这不是并行性,多个操作“在 CPU 的监督下,通过适当的调度一次运行一个”。例如,“try/catch”块(显然)是使用任务实现的。

因此,要回答您的第一个问题,是的,您需要了解共享状态,而对于第二个问题,不,只要您以某种方式访问​​全局状态(其中当前目录是一个方面)我不完全确定每个任务应该按照您描述的方式有自己的语义;相反,您只需要以这样的方式设计您的任务,使它们考虑到状态共享的事实,并采取相应的行动。

作为第二个的另一个例子,考虑两个单独的任务,它们“产生”需要“消耗”的输出。如果您依赖于基于全局状态的任一任务的适当消耗,那么您的任务完全有可能在设计上应根据共享全局状态进行适当的行为。这是一个简单的例子:

d = 0;

function report()
  global d;
  for i in 1:4
    if iseven(d); produce("D is Even\n"); else; produce("D is Odd\n"); end
  end
end

task1 = Task( report );
task2 = Task( report );

for i in 1:4
  d = i;
  consume(task1) |> print;
  consume(task2) |> print;
end
D is Odd
D is Odd
D is Even
D is Even
D is Odd
D is Odd
D is Even
D is Even

PS. the latest julia build is informing me that "produce" and "consume" are being deprecated in favour of "Channels", but presumably the point stands.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Julia 语言 - @async 任务中的状态 :: 当前目录 的相关文章

随机推荐