即:cd("some_dir") do # stuffend我们已经在 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 endendrunme("a")runme("b")输出:(显然)a::bb::b(摘要)-尽管这几乎不是问题,但应该可以对其进行搜索和记录(因为这可能是同步错误的来源).与全局变量的区别(大约是cd()的状态)-可以使用let语句在闭包中捕获变量,而当前目录则不能.尽管这甚至不是特定于编程语言的(而是操作系统进程的问题),但我认为该语法确实给人一种局部性的幻想(类似于python'with'块或许多其他设备).因此,最重要的是,除非有一天有一种方法可以将切换回"到Task/block/closure的处理程序(类似于finally以某种方式阻止)解决方案我没有明确了解内部结构或特定实现,这是我个人的有根据的猜测,很高兴被实际的julia开发人员更正,但是我认为Tasks本身并不共享当前目录",而是更普遍地共享状态".您的示例将对全局变量执行相同的操作: # in testscript.jlvar = 0;function runme(val) global var = val+1; return t = @async begin sleep(1) println(val,"::",var); endendrunme(1)runme(3) # in the REPL sessionjulia> include("testo.jl"); 1::4 3::4 但是,共享(全局)状态是一项功能,而不是错误.这与进程(julia实现真正的并行性的方式)相反,后者不共享状态,因此工作人员之间的所有通信都需要通过套接字进行.虽然确实需要注意这一点,但它也非常有用和必要.在这方面,任务(或协程)不用于实现并行性或局限性.它们是协作式多任务处理的一种形式",即在同一线程上实现多次运行操作的一种方式;这不是并行性,多个操作在CPU的监督下,以适当的调度一次运行一次".例如,尝试/捕获"块(显然)是使用任务"实现的.因此,要回答第一个问题,是的,您需要了解共享状态,对于第二个问题,则是不,在某种程度上,您正在使用任务"以某种方式访问​​全局状态(当前目录是其中的一个方面)我不确定每个Task都应该以您描述的方式具有自己的语义.取而代之的是,您只需要以这样一种方式设计任务,即它们考虑到共享状态的事实并采取相应的行动.作为第二个示例的另一个示例,请考虑两个单独的任务,这些任务产生"需要消耗"的输出.如果您基于全局状态依赖于任一任务的适当消耗,则完全有可能设计使您的任务相对于共享的全局状态表现适当.这是一个简单的例子: 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 endendtask1 = Task( report );task2 = Task( report );for i in 1:4 d = i; consume(task1) |> print; consume(task2) |> print;end D is OddD is OddD is EvenD is EvenD is OddD is OddD is EvenD is Even PS.最新的julia版本通知我,不赞成使用生产"和消费",而推荐使用渠道",但这大概是关键所在. I've noticed (read: caught a production bug) different Tasks in Julia - do not have their own working directory, but that the current directory - is shared. I realise in an OS level this is kind of obvious (a process has a working-directory).My question is first - is there any other obvious or less obvious global state I should watch out for (obviously environment variables, or any global variables).Second - should this be more documented, or avoided by the task abstraction, - a "Task" in an abstraction, it could (theoretically) have it's own semantics, like moving back to a working directory.We've solved the product bug by removing any 'cd()' call from within the code, the point is - the cd() with closure abstraction was giving us the illusion that this might be safe to use.ie:cd("some_dir") do # stuffendWe've had this sort of code working in Mux endpoints.My minimal reproduction of the issue, isfunction runme(path) mkpath(path) abs_path = realpath(path) return t = @async begin cd(abs_path) do sleep(1) println(path,"::",(pwd()|>splitdir)[2]) end endendrunme("a")runme("b")output: (obviously)a::bb::bEdit: (summary) - though this is almost not a question - this should be searchable and documented (as it's a possible source of synchronisation bugs).The difference to just a global variable (about the state of 'cd()') - a variable can be captured in a closure using a let statement, while the current directory cannot. While this is not even programming language specific (but a OS-process issue) - I think the syntax does give an illusion of locality (similar to python 'with' blocks, or many other devices).Thus the bottom line is that the 'cd' abstraction should not be used in any production utility, unless one day there's a way to set a handler for 'switching back' into a Task/block/closure (similar to the finally blocks in a way) 解决方案 I'm not explicitly aware of the internals or particular implementation, and this is my personal educated guess and happy to be corrected by an actual julia dev, but I think it's not a case that Tasks share "the current directory" per se, but that they more generally share "state". Your example will behave the same way with global variables instead:# in testscript.jlvar = 0;function runme(val) global var = val+1; return t = @async begin sleep(1) println(val,"::",var); endendrunme(1)runme(3)# in the REPL sessionjulia> include("testo.jl"); 1::4 3::4However, the sharing of (global) state is a feature, not a bug. This is in contrast to processes (which is the way in which julia achieves true parallelism), which do not share state, and therefore all communications between workers need to be done via sockets.While one does need to be careful with this, it can also be very useful and necessary. Tasks (or coroutines) are not used to achieve parallelism or confinement in that regard. They are "a form of cooperative multitasking", i.e. a way to achieve multiply running operations on the same thread; this is not parallelism, the multiple operations are run "one at a time with appropriate scheduling, as supervised by the CPU". For instance "try/catch" blocks are (apparently) implemented using Tasks.So, to answer your first question, yes, you need to be aware of the shared state, and to the second question, no, to the extent that you're using the Tasks in a way that accesses somehow the global state (of which the current directory is an aspect) I'm not entirely sure each Task should have its own semantics in the way you describe; instead you just need to design your tasks in such a way that they take the fact that state is shared into account, and act accordingly.As a further example of the second, consider two separate tasks that "produce" outputs that need to be "consumed". If you rely on the appropriate consumption from either task based on a global state, then it is entirely possible that your task should behave appropriately with respect to the shared global state by design. Here's a trivial example of this: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 endendtask1 = Task( report );task2 = Task( report );for i in 1:4 d = i; consume(task1) |> print; consume(task2) |> print;endD is OddD is OddD is EvenD is EvenD is OddD is OddD is EvenD is EvenPS. the latest julia build is informing me that "produce" and "consume" are being deprecated in favour of "Channels", but presumably the point stands. 这篇关于朱莉娅语言-@async任务中的状态::当前目录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-03 21:40