Elixir 如何并发执行函数

Elixir 如何并发执行函数,elixir,Elixir,我是FP和elixir的新手,我正在尝试同时执行以下功能。但这在read()上被卡住了。我尝试了Task.async和spawn\u link并在其中传递函数,但没有成功 defmodule MyFile do def start() do read() write() #Task.async(read()) #Task.async(write()) end def read() do case 1 do 1 -> IO.puts "this is one" 2

我是FP和elixir的新手,我正在尝试同时执行以下功能。但这在read()上被卡住了。我尝试了
Task.async
spawn\u link
并在其中传递函数,但没有成功

defmodule MyFile do


def start() do

read()
write()


#Task.async(read())
#Task.async(write())
end



def read() do
case 1 do
  1 -> IO.puts "this  is one"
  2 -> IO.puts "this is two"
  _ -> IO.puts "this is dont care "
end
   read()
end


def write() do

case 1 do
  1 -> IO.puts "THIS IS ONE OF WRITE"
  2 -> IO.puts "THIS IS TWO OF WRITE"
  _ -> IO.puts "this is dont care "
end
   write()
end


end

它正在控制台上打印
“这是一个”
,因此
start()
中的
write()
函数永远不会执行,因为控件位于
read()
中。在这种情况下,如何以某种方式同时启动和执行这两个函数?

您应该使用另一个进程启动
读取
写入
函数。之后,他们将消息发送回主进程,如下所示,以同时打印消息。下面的代码可以帮助您了解更多

defmodule Doan do

def start() do
  current = self()
  spawn(Doan, :read, [current])
  spawn(Doan, :write, [current])
  loop()
end

def loop do
  receive do
    {:read, 1} -> IO.puts "this  is one"
    {:write, 1} -> IO.puts "THIS IS ONE OF WRITE"
    {:read, 2} -> IO.puts "this is two"
    {:write, 2} -> IO.puts "THIS IS TWO OF WRITE"
    _ -> IO.puts "this is dont care "
  end
  loop()
end

def read(pid) do
  send pid, {:read, 1}
  :timer.sleep(500)
  read(pid)
end

def write(pid) do
  send pid, {:write, 1}
  :timer.sleep(500)
  write(pid)
end
end
在shell上的结果是:


您应该使用另一个进程启动
读取
写入
功能。之后,他们将消息发送回主进程,如下所示,以同时打印消息。下面的代码可以帮助您了解更多

defmodule Doan do

def start() do
  current = self()
  spawn(Doan, :read, [current])
  spawn(Doan, :write, [current])
  loop()
end

def loop do
  receive do
    {:read, 1} -> IO.puts "this  is one"
    {:write, 1} -> IO.puts "THIS IS ONE OF WRITE"
    {:read, 2} -> IO.puts "this is two"
    {:write, 2} -> IO.puts "THIS IS TWO OF WRITE"
    _ -> IO.puts "this is dont care "
  end
  loop()
end

def read(pid) do
  send pid, {:read, 1}
  :timer.sleep(500)
  read(pid)
end

def write(pid) do
  send pid, {:write, 1}
  :timer.sleep(500)
  write(pid)
end
end
在shell上的结果是:


您的
Task.async/1
就快完成了。唯一的问题是您需要提供一个[anonymous]函数作为其参数,而您需要调用该函数

def模块RW do
def start()do
#          ⇓⇓⇓⇓⇓⇓⇓ 在这里
Task.async(&read/0)#或fn->read()结束
Task.async(&write/0)
:好的
结束
def读取(计数器\\10)do
爱娥说“这是一个”

除非counter您使用
Task.async/1
就快到了。唯一的问题是您需要提供一个[anonymous]函数作为其参数,而您需要调用该函数

def模块RW do
def start()do
#          ⇓⇓⇓⇓⇓⇓⇓ 在这里
Task.async(&read/0)#或fn->read()结束
Task.async(&write/0)
:好的
结束
def读取(计数器\\10)do
爱娥说“这是一个”

除非反感谢您的详细解释,这与乒乓球的例子是一样的。然而,我读到我们不应该在不需要的时候使用流程。例如,保持计算器实现的简单性,而不是将它们放在GenServer中。所以我觉得这里不需要流程。您知道我可以在这里同时运行函数的方法吗?在Elixir/Erlang中,似乎没有不使用process@bxdoan当然,我们可以看到我的答案,关于生成两个
任务
实例的实现,没有任何问题。感谢您的详细解释,这与乒乓球示例相同。然而,我读到我们不应该在不需要的时候使用流程。例如,保持计算器实现的简单性,而不是将它们放在GenServer中。所以我觉得这里不需要流程。您知道我可以在这里同时运行函数的方法吗?在Elixir/Erlang中,似乎没有不使用process@bxdoan当然,我们可以看到我对生成两个
任务
实例的实现的回答,没有任何问题。旁注:与控制流程的解决方案不同,这是真正的并行。请注意后面的两个
“这是WRITE的一个”
。谢谢,这很酷!你能告诉我其他的答案吗。对于我应该真正使用流程的内容?嗯,
Task.async/1
确实产生了一个流程。回答你的问题,除非你知道你需要一个过程,否则你应该避免它。这很简单,以后你会遇到需要这个过程的情况,你自己也会明白这一点。例如,持久化状态总是需要进程。旁注:与控制进程的解决方案不同,此解决方案是真正并发的。请注意后面的两个
“这是WRITE的一个”
。谢谢,这很酷!你能告诉我其他的答案吗。对于我应该真正使用流程的内容?嗯,
Task.async/1
确实产生了一个流程。回答你的问题,除非你知道你需要一个过程,否则你应该避免它。这很简单,以后你会遇到需要这个过程的情况,你自己也会明白这一点。例如,持久化状态始终需要流程。