elixir语言教程5:并发编程


erlang教程基础入门🔥 编程基础🔥 数据结构🔥 递归🔥 并发编程
elixir教程基础入门🔥 编程基础🔥 模式匹配🔥 递归枚举

spwan

elixir继承了erlang的高并发特性,提供轻量且易用的多进程编程方法,通过spawn函数调用函数,就可以实现新进程的开启。

iex(1)> spawn(fn -> 1+2 end)
#PID<0.108.0>

其中fn->1+2 end是一个匿名函数,通过spawn调用之后,会返回一个进程号。通过self函数,可以得到主进程的ID

iex(2)> self()
#PID<0.106.0>

为了检测进程是否存在,可以通过Process.alive函数

iex(3)> pid = spawn(fn -> 1+2 end)
#PID<0.110.0>
iex(4)> Process.alive?(pid)
false

进程通信

elixir中,通过send, recieve来完成进程通信,示例如下

# 文件Example.ex
defmodule Example do
  def listen do
    receive do
      {:ok, "hello"} -> IO.puts("world")
    end
    listen()
  end
end

其功能是,当有进程发送:ok这个原子以及"Hello"这个字符串的时候,输出"world"

正常来说,作为某个监听进程,监听函数必然要放在一个死循环里,但elixir并不支持循环,所以在listen的最后一行又调用了自身,即通过递归的方式创建了一个永不停歇的监听工具。

接下来在命令行中调用,效果如下

>iex Example.ex
iex(1)> pid = spawn(Example, :listen, [])
#PID<0.113.0>
iex(2)> send pid, {:ok, "hello"}
world
{:ok, "hello"}
iex(3)> send pid, {:ok, "hello"}
world
{:ok, "hello"}
iex(4)> send pid, {:ok, "hell"}
{:ok, "hell"}

其中spawn函数与之前开启进程的时候稍有区别,即这回是从模块中调用函数,所以spawn的输入参数变成了3个,分别是模块名,模块中的函数名,以及函数参数。新进程创建之后,被赋予给pid

然后,通过send函数向pid发送消息,连发两次,两次的结果都返回了world,说明listen函数一直在工作,递归写法起到了作用。但第三次发送时,"hello"并没有匹配上,所以也就没继续输出world了。

如果想关闭这个进程,那么可以通过Process.exit函数

iex(5)> Process.exit(pid, :kill)
true
iex(6)> send pid, {:ok, "hello"}
{:ok, "hello"}

通过标识原子:kill来让pid这个进程被关闭,这样即便再向其发送:ok,也不会再有回复了,而且调用Process.alive?也可以查看进程的死活。

spawn_link

由于进程之间是单独运行的,彼此并不相干,所以一个进程崩掉,对另一个进程并不会有影响。如果希望进程错误可以被链接到父进程中,则可用spawn_link函数取代spawn函数。

下面再命令行中测试一下这两个函数的差异

iex(1)> spawn(fn -> 1/0 end)
#PID<0.109.0>
iex(2)>
22:25:45.267 [error] Process #PID<0.109.0> raised an exception
** (ArithmeticError) bad argument in arithmetic expression
    :erlang./(1, 0)
    iex:1: (file)

在上面的代码中1/0是必然会报错的,而通过spawn开启新进程调用这个错误的函数,最终尽管也报错了,但主进程并没有受到影响。

接下来通过spawn_link函数重新尝试一下

iex(2)> spawn_link(fn -> 1/0 end)

22:25:54.750 [error] Process #PID<0.111.0> raised an exception
** (ArithmeticError) bad argument in arithmetic expression
    :erlang./(1, 0)
    iex:2: (file)
** (EXIT from #PID<0.106.0>) shell process exited with reason: an exception was raised:
    ** (ArithmeticError) bad argument in arithmetic expression
        :erlang./(1, 0)
        iex:2: (file)

Interactive Elixir (1.14.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>

可以发现除了进程报错之外,shell所在进程也出现了问题,最后不得不重启命令行,代码又从iex(1)开始了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微小冷

请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值