Jer*_*ska 2 concurrency erlang elixir spawn
我在 Elixir 脚本中编写了一个模块 SC wget.exs,. 该模块SC 利用 Erlang 的操作系统模块来执行复杂的命令并将其输出打印在屏幕上。我在脚本中使用该模块一次下载多个包wget:
#!/usr/bin/env elixir\n\ndefmodule SC do\n def run(cmmnd) do\n output = :os.cmd(String.to_charlist(cmmnd)) \n IO.puts output\n end\nend\n\ndefmodule Downloader do\n def download_packages do\n lst_f_pckgs = "wget-list-sysv"\n\n #System.cmd("wget", ["https://www.linuxfromscratch.org/lfs/view/stable/#{lst_f_pckgs}"])\n SC.run("wget -c https://www.linuxfromscratch.org/lfs/view/stable/#{lst_f_pckgs}")\n \n {:ok, file_content} = File.read(lst_f_pckgs)\n arr_f_pckgs = String.split(file_content, ~r/\\s+/)\n\n tasks =\n arr_f_pckgs\n |> Enum.map(fn l ->\n #Task.async(fn -> System.cmd("wget", [l]) end)\n Task.async(fn -> SC.run("wget -c #{l}") end)\n end)\n\n tasks\n |> Enum.each(&Task.await/1)\n\n IO.puts "All of them are downloaded."\n end\nend\n\nDownloader.download_packages()\n\n\nRun Code Online (Sandbox Code Playgroud)\n该脚本首先要下载一个文本文件,其中包含要下载的软件包列表,这部分脚本工作正常,然后继续并行下载所有软件包。当使用我的模块时,SC脚本开始下载,但随后退出,我得到以下输出:
5550K .......... .......... .......... .......... .......... 98% 11.6M 0s\n 5600K .......... .......... .......... .......... .......... 99% 457K 0s\n 5650K .......... .......... .. 100% 145M=8.1s\n\n2024-01-15 13:38:05 (702 KB/s) - \xe2\x80\x98coreutils-9.3.tar.xz\xe2\x80\x99 saved [5808696/5808696]\n\n\n--2024-01-15 13:37:56-- https://github.com/systemd/systemd/archive/v254/systemd-254.tar.gz\nResolving github.com (github.com)... 140.82.121.3\nConnecting to github.com (github.com)|140.82.121.3|:443... connected.\nHTTP request sent, awaiting response... 302 Found\nLocation: https://codeload.github.com/systemd/systemd/tar.gz/refs/tags/v254 [following]\n--2024-01-15 13:37:56-- https://codeload.github.com/systemd/systemd/tar.gz/refs/tags/v254\nResolving codeload.github.com (codeload.github.com)... 140.82.121.10\nConnecting to codeload.github.com (codeload.github.com)|140.82.121.10|:443... connected.\nHTTP request sent, awaiting response... 200 OK\nLength: unspecified [application/x-gzip]\nSaving to: \xe2\x80\x98systemd-254.tar.gz\xe2\x80\x99\n\n 0K .......... .......... .......... .......... .......... 267K\n 50K .......... .......... .......... .......... .......... 27.2M\n 100K .......... .......... .......... .......... .......... 442K\n 150K .......... .......... .......... .......... .......... 202K\n[many similar lines]\n8.10M 0s\n 6200K .......... .......... .......... .......... .......... 97% 31.7M 0s\n 6250K .......... .......... .......... .......... .......... 98% 1.48M 0s\n 6300K .......... .......... .......... .......... .......... 98% 700K 0s\n 6350K .......... .......... .......... .......... .......... 99% 5.73M 0s\n 6400K .......... .......... ....... 100% 460M=10s\n\n2024-01-15 13:38:07 (639 KB/s) - \xe2\x80\x98grub-2.06.tar.xz\xe2\x80\x99 saved [6581924/6581924]\n\n\n** (exit) exited in: Task.await(%Task{mfa: {:erlang, :apply, 2}, owner: #PID<0.96.0>, pid: #PID<0.110.0>, ref: #Reference<0.1214714622.3043557380.75212>}, 5000)\n ** (EXIT) time out\n (elixir 1.14.0) lib/task.ex:830: Task.await/2\n (elixir 1.14.0) lib/enum.ex:975: Enum."-each/2-lists^foreach/1-0-"/2\n wget.exs:28: Downloader.download_packages/0\n\nRun Code Online (Sandbox Code Playgroud)\n而如果我使用 Elixir 的System module the script does its job and prints “所有这些都已下载。”`到屏幕上。
返回的错误是:
exited in: Task.await(..., 5000)
** (EXIT) time out
Run Code Online (Sandbox Code Playgroud)
默认超时时间为Task.await5 秒。大概下载一堆文件需要更长的时间。
:infinity对于您的用例或者如果您不想超时,请将超时增加到某个合理的值。
|> Enum.each(&Task.await(&1, :infinity))
Run Code Online (Sandbox Code Playgroud)