首页 > 系统服务 > 详细

多进程

时间:2019-09-11 19:41:47      阅读:67      评论:0      收藏:0      [点我收藏+]

  使用spawn创建一个新进程,其第一个参数是模块名、第二个参数是函数名、第三个参数是参数列表。spawn会返回一个进程标识符,通常叫做PID。

defmodule Spawn1 do
    def greet do
        receive do
            {sender, msg} ->
                send sender, { :ok, "Hello #{msg}" }
            # code
        end
        
    end
end

spawn(SpawnBasic, :greet, [])        #"Hello"

 

进程间发送消息

  使用send发送消息,第一个参数是接收方pid、第二个参数是要发送的消息,通常是原子或者元组。使用receive等待消息,它的用法比较像case。

#以下代码都在同一个文件中。
defmodule Spawn1 do def greet do
receive do {sender, msg} -> send sender, { :ok, "Hello #{msg}" } # code end end end pid = spawn(Spawn1, :greet, []) send pid, {self, "World!"} receive do {:ok, message} -> IO.puts message end

  上述代码如果想要发送第二条数据,就会导致iex被挂起。因为greet函数在处理完receive后,就退出了。我们永远等不来receive的相应。我们可以使用 after 指定receive在规定时间内未到达就超时。

receive do
    {:ok, message} ->
        IO.puts message
    after 500 ->    #receive在等待500毫秒后,消息未到达就会退出
        IO.puts "The greeter han gone away"
end

 

  我们可以使用递归来处理多条消息。greet:

def greet do
    receive do
        {sender, msg} ->
            send, sender, { :ok, "Hello, #{msg}" }
            greet
        end
    end
end

pid = spawn(Spawn1, :greet, [])
send pid, {self, "World!"}

receive do
    {:ok, message} ->
        IO.puts message            # "Hello, World!"
end

pid = spawn(Spawn1, :greet, [])
send pid, {self, "kermit!"}

receive do
    {:ok, message} ->
        IO.puts message            # "Hello, Kermit!"
    after 500 ->
        IO.puts "The greeter has gone away"
end

 

进程开销

  很小。

 

  进程调用exit(:boom)会以状态码99退出。

 

  关联两个进程,使用spawn_link会创建一个进程并和调用者相关联。

defmodule Link2 do 
    import :timer, only: [ sleep: 1 ]

    def sad_function do
        sleep 500
        exit(:boom)
    end
    def run do
        spawn_link(Link2, :sad_function, [])
        receive do
            msg ->
                IO.puts "<MESSAGE RECEIVED: #{inspect msg}"
        after 1000 ->
            IO.puts "Nothing ... "
        end
    end
end

  子进程结束,然后它会结束整个应用,这是关联进程的默认行为,当其中一个进程非正常退出时会把另一个进程也杀死。

  设置Peocess.flag(:trap_exit, true),可以捕获进程退出时的消息。

  创建进程时,可以使用spawn_monitor开启监控(创建 + 监控),也可以使用Process.monitor监控已经存在的进程。当使用Process.monitor时,在调用监控完成前被监控进程死了,就不会受到通知。然而,spawn_link和spawn_monitor操作符合原子性,所以总能捕获到错误。 

 

并行map

  普通map返回列表,该列表是某个收集的每个元素应用于某个函数的结果。并行版本做同样的事情,但每个元素在独立的进程里应用于函数。

defmodule Parallel do
    def pmap(collection, fun) do
        me = self
        collection
        |> Enum.map(fn (elem) ->     #双重嵌套函数
            spawn_link fn -> (send me, { self, fun.(elem) } ) end    #返回一组PID,每个PID内都运行了一个计算函数,将自身PID和结果发送给主进程
        end)
        |> Enum.map(fn (pid) ->    #在主进程中等待结果
            receive do {^pid, resuet } -> result end
        end)
    end
end

 

多进程

原文:https://www.cnblogs.com/lr1402585172/p/11507966.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!