concurrency - Julia 语言 - @async tasks::Current-Directory 中的状态

标签 concurrency julia working-directory

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

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

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

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

即:

cd("some_dir") do
  # stuff
end

我们在 Mux 中使用过此类代码端点。

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

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” block 或许多其他设备)。

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

最佳答案

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

# 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” block (显然)是使用任务实现的。

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

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

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

<子>附言。最新的 julia 版本通知我“生产”和“消费”已被弃用,取而代之的是“ channel ”,但大概是这样。

关于concurrency - Julia 语言 - @async tasks::Current-Directory 中的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44571713/

相关文章:

types - Julia 中的值类型实例

macros - Julia:如何在宏中使用 kwargs?

ios - Grand Central Dispatch,不确定我是否完全理解这一点,这就是我的使用方式

java - 我们如何在 Java 中测试 Actors?

java - Java 与 Clojure 的良好并发示例

java - Camunda BPM 的 JavaDelegate 类应该是线程安全的吗?

julia - 如何在 Julia 中使用 vegas 计算具有无限边界的高维多重积分

visual-studio - 在 Visual Studio 2008 中为自定义构建步骤设置工作目录

git - 工作目录和本地存储库有什么区别?

linux - 使用自定义环境运行脚本。变种。和没有额外外壳的工作目录