杀死进程并在erlang中运行程序
Posted
技术标签:
【中文标题】杀死进程并在erlang中运行程序【英文标题】:kill process and run a program in erlang 【发布时间】:2013-02-08 05:29:08 【问题描述】:我用erlang开发一个程序
我用这个命令运行这个程序:
./build.sh && ./deploy.sh ./erl_start.sh
我想知道在 verify 函数中进行 test,这些函数存储在我的程序的文件 model.erl 中
在 verify 函数中,我应该找到并杀死我的程序(当前程序)的进程 我想运行程序
verify(Val)->
if Val =:=40 ->
%% kill the process of my program
%% run this commande ./build.sh && ./deploy.sh ./erl_start.sh
true -> ok
end.
所以我想我会尝试
verify(Val)->
if Val =:=40 ->
exit(Pid,Reason), %% but I should know the pid of the current program
os_cmd("./build.sh && ./deploy.sh ./erl_start.sh");
true -> ok
end.
知道当前程序的 pid --> 我有一个正在运行的应用程序,在这个应用程序的代码中我应该有办法知道这个应用程序的 pid 以使其停止
目前
我试试这个功能:
verify(Val)->
if Val =:=40 ->
Pid = self(),
io:format("~w~n",[Pid]),
spawn(fun() -> exit(Pid, kill) end),
LsOut = os:cmd("./build.sh && ./deploy.sh && ./erl_start.sh");
true -> ok
end.
当我测试这个功能时,我遇到了这个错误:
1> model:verify(40).
<0.144.0>
** exception exit: killed
我的目标是:
我有一个用 Erlang 开发的应用程序来运行我需要做的这个应用程序:./build.sh && ./deploy.sh && ./erl_start.sh
我想创建一个函数(在我们的例子中是函数 verify),它将与 Ctrl + C 执行相同的操作,然后执行 ./build.sh && ./deploy.sh && ./erl_start .sh 意思是停止应用程序并再次运行此应用程序
我也测试了你的命令,我得到了这个结果:
1> [io:format("~p : ~p~n",[Pid,erlang:process_info(Pid,current_function)]) || Pid <- processes()].
<0.0.0> : current_function,init,loop,1
<0.3.0> : current_function,erl_prim_loader,loop,3
<0.5.0> : current_function,gen_event,fetch_msg,5
<0.6.0> : current_function,gen_server,loop,6
<0.8.0> : current_function,application_master,main_loop,2
<0.9.0> : current_function,application_master,loop_it,4
<0.10.0> : current_function,gen_server,loop,6
<0.11.0> : current_function,gen_server,loop,6
<0.12.0> : current_function,gen_server,loop,6
<0.13.0> : current_function,global,loop_the_locker,1
<0.14.0> : current_function,global,collect_deletions,2
<0.15.0> : current_function,global,loop_the_registrar,0
<0.16.0> : current_function,gen_server,loop,6
<0.18.0> : current_function,gen_server,loop,6
<0.19.0> : current_function,gen_server,loop,6
<0.20.0> : current_function,code_server,loop,1
<0.21.0> : current_function,gen_server,loop,6
<0.22.0> : current_function,standard_error,server_loop,1
<0.23.0> : current_function,gen_server,loop,6
<0.24.0> : current_function,user_drv,server_loop,5
<0.25.0> : current_function,group,server_loop,3
<0.26.0> : current_function,group,server_loop,3
<0.27.0> : current_function,shell,shell_rep,4
<0.28.0> : current_function,gen_server,loop,6
<0.29.0> : current_function,gen_server,loop,6
<0.36.0> : current_function,application_master,main_loop,2
<0.37.0> : current_function,application_master,loop_it,4
<0.38.0> : current_function,gen_server,loop,6
<0.39.0> : current_function,gen_event,fetch_msg,5
<0.40.0> : current_function,gen_server,loop,6
<0.41.0> : current_function,gen_server,loop,6
<0.44.0> : current_function,gen_server,loop,6
<0.45.0> : current_function,mnesia_locker,loop,1
<0.46.0> : current_function,gen_server,loop,6
<0.47.0> : current_function,mnesia_tm,doit_loop,1
<0.48.0> : current_function,gen_server,loop,6
<0.49.0> : current_function,gen_server,loop,6
<0.53.0> : current_function,gen_server,loop,6
<0.54.0> : current_function,gen_server,loop,6
<0.63.0> : current_function,disk_log,loop,1
<0.65.0> : current_function,gen_server,loop,6
<0.66.0> : current_function,gen_server,loop,6
<0.67.0> : current_function,gen_server,loop,6
<0.68.0> : current_function,gen_server,loop,6
<0.69.0> : current_function,mnesia_late_loader,loop,1
<0.105.0> : current_function,application_master,main_loop,2
<0.106.0> : current_function,application_master,loop_it,4
<0.107.0> : current_function,gen_server,loop,6
<0.108.0> : current_function,gen_server,loop,6
<0.109.0> : current_function,gen_server,loop,6
<0.110.0> : current_function,gen_server,loop,6
<0.111.0> : current_function,gen_server,loop,6
<0.112.0> : current_function,gen_server,loop,6
<0.113.0> : current_function,gen_server,loop,6
<0.114.0> : current_function,gen_server,loop,6
<0.115.0> : current_function,gen_server,loop,6
<0.117.0> : current_function,gen_server,loop,6
<0.118.0> : current_function,gen_server,loop,6
<0.119.0> : current_function,gen_server,loop,6
<0.120.0> : current_function,gen_server,loop,6
<0.121.0> : current_function,prim_inet,accept0,2
<0.123.0> : current_function,gen_server,loop,6
<0.124.0> : current_function,gen_server,loop,6
<0.125.0> : current_function,gen_server,loop,6
<0.126.0> : current_function,gen_server,loop,6
<0.127.0> : current_function,prim_inet,accept0,2
<0.129.0> : current_function,gen_server,loop,6
<0.130.0> : current_function,gen_server,loop,6
<0.131.0> : current_function,gen_server,loop,6
<0.132.0> : current_function,gen_server,loop,6
<0.133.0> : current_function,prim_inet,accept0,2
<0.135.0> : current_function,gen_server,loop,6
<0.136.0> : current_function,gen_server,loop,6
<0.137.0> : current_function,gen_server,loop,6
<0.138.0> : current_function,gen_server,loop,6
<0.139.0> : current_function,prim_inet,accept0,2
<0.140.0> : current_function,gen_server,loop,6
<0.143.0> : current_function,os,start_port_srv_loop,2
<0.144.0> : current_function,erl_eval,do_apply,5
[ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,
ok,ok,ok,ok,ok,ok,ok,ok,ok,ok|...]
我有第二个命令:
1> [io:format("~p : ~p~n",[Pid,erlang:process_info(Pid,initial_call)]) || Pid <- processes()].
<0.0.0> : initial_call,otp_ring0,start,2
<0.3.0> : initial_call,erlang,apply,2
<0.5.0> : initial_call,proc_lib,init_p,5
<0.6.0> : initial_call,erlang,apply,2
<0.8.0> : initial_call,proc_lib,init_p,5
<0.9.0> : initial_call,application_master,start_it,4
<0.10.0> : initial_call,proc_lib,init_p,5
<0.11.0> : initial_call,proc_lib,init_p,5
<0.12.0> : initial_call,proc_lib,init_p,5
<0.13.0> : initial_call,erlang,apply,2
<0.14.0> : initial_call,erlang,apply,2
<0.15.0> : initial_call,erlang,apply,2
<0.16.0> : initial_call,proc_lib,init_p,5
<0.18.0> : initial_call,proc_lib,init_p,5
<0.19.0> : initial_call,proc_lib,init_p,5
<0.20.0> : initial_call,erlang,apply,2
<0.21.0> : initial_call,proc_lib,init_p,5
<0.22.0> : initial_call,standard_error,server,2
<0.23.0> : initial_call,proc_lib,init_p,5
<0.24.0> : initial_call,user_drv,server,2
<0.25.0> : initial_call,group,server,3
<0.26.0> : initial_call,group,server,3
<0.27.0> : initial_call,erlang,apply,2
<0.28.0> : initial_call,proc_lib,init_p,5
<0.29.0> : initial_call,proc_lib,init_p,5
<0.36.0> : initial_call,proc_lib,init_p,5
<0.37.0> : initial_call,application_master,start_it,4
<0.38.0> : initial_call,proc_lib,init_p,5
<0.39.0> : initial_call,proc_lib,init_p,5
<0.40.0> : initial_call,proc_lib,init_p,5
<0.41.0> : initial_call,proc_lib,init_p,5
<0.44.0> : initial_call,proc_lib,init_p,5
<0.45.0> : initial_call,proc_lib,init_p,5
<0.46.0> : initial_call,proc_lib,init_p,5
<0.47.0> : initial_call,proc_lib,init_p,5
<0.48.0> : initial_call,proc_lib,init_p,5
<0.49.0> : initial_call,proc_lib,init_p,5
<0.53.0> : initial_call,proc_lib,init_p,5
<0.54.0> : initial_call,proc_lib,init_p,5
<0.63.0> : initial_call,proc_lib,init_p,5
<0.65.0> : initial_call,proc_lib,init_p,5
<0.66.0> : initial_call,proc_lib,init_p,5
<0.67.0> : initial_call,proc_lib,init_p,5
<0.68.0> : initial_call,proc_lib,init_p,5
<0.69.0> : initial_call,proc_lib,init_p,5
<0.105.0> : initial_call,proc_lib,init_p,5
<0.106.0> : initial_call,application_master,start_it,4
<0.107.0> : initial_call,proc_lib,init_p,5
<0.108.0> : initial_call,proc_lib,init_p,5
<0.109.0> : initial_call,proc_lib,init_p,5
<0.110.0> : initial_call,proc_lib,init_p,5
<0.111.0> : initial_call,proc_lib,init_p,5
<0.112.0> : initial_call,proc_lib,init_p,5
<0.113.0> : initial_call,proc_lib,init_p,5
<0.114.0> : initial_call,proc_lib,init_p,5
<0.115.0> : initial_call,proc_lib,init_p,5
<0.117.0> : initial_call,proc_lib,init_p,5
<0.118.0> : initial_call,proc_lib,init_p,5
<0.119.0> : initial_call,proc_lib,init_p,5
<0.120.0> : initial_call,proc_lib,init_p,5
<0.121.0> : initial_call,proc_lib,init_p,5
<0.123.0> : initial_call,proc_lib,init_p,5
<0.124.0> : initial_call,proc_lib,init_p,5
<0.125.0> : initial_call,proc_lib,init_p,5
<0.126.0> : initial_call,proc_lib,init_p,5
<0.127.0> : initial_call,proc_lib,init_p,5
<0.129.0> : initial_call,proc_lib,init_p,5
<0.130.0> : initial_call,proc_lib,init_p,5
<0.131.0> : initial_call,proc_lib,init_p,5
<0.132.0> : initial_call,proc_lib,init_p,5
<0.133.0> : initial_call,proc_lib,init_p,5
<0.135.0> : initial_call,proc_lib,init_p,5
<0.136.0> : initial_call,proc_lib,init_p,5
<0.137.0> : initial_call,proc_lib,init_p,5
<0.138.0> : initial_call,proc_lib,init_p,5
<0.139.0> : initial_call,proc_lib,init_p,5
<0.140.0> : initial_call,proc_lib,init_p,5
<0.143.0> : initial_call,erlang,apply,2
<0.144.0> : initial_call,erlang,apply,2
[ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,
ok,ok,ok,ok,ok,ok,ok,ok,ok,ok|...]
【问题讨论】:
【参考方案1】:您可以使用 exit(Pid, Reason) 和 os_cmd/1 函数来执行您的命令。
如果要重启虚拟机,erl应该用-heart启动并使用init:reboot重启虚拟机
【讨论】:
但是我怎么知道程序的pid, 使用:erlang:self/0,但随后程序会自行终止,os:cmd/1 将永远不会运行? 你可以生成另一个为你做这件事的进程 Pid = self(), spawn(fun() -> exit(Pid, kill) end)。我认为你应该阅读一些关于 Erlang 的教程。 learnyousomeerlang.com 很不错。【参考方案2】:您可以使用函数erlang:processes()
知道在虚拟机中运行的进程的 pid 是什么。然后使用erlang:process_info/1 or /2
可以获得当前函数、初始调用者的信息...
例如从 shell 调用你可以打印:
1> [io:format("~p : ~p~n",[Pid,erlang:process_info(Pid,current_function)]) || Pid <- processes()].
<0.0.0> : current_function,init,loop,1
<0.3.0> : current_function,erl_prim_loader,loop,3
<0.5.0> : current_function,gen_event,fetch_msg,5
<0.6.0> : current_function,gen_server,loop,6
...
或:
2> [io:format("~p : ~p~n",[Pid,erlang:process_info(Pid,initial_call)]) || Pid <- processes()].
<0.0.0> : initial_call,otp_ring0,start,2
<0.3.0> : initial_call,erlang,apply,2
<0.5.0> : initial_call,proc_lib,init_p,5
<0.6.0> : initial_call,erlang,apply,2
如果您将 io:format/2 替换为对正确的初始调用者进行过滤的终止函数,则可以解决问题。
除此之外,我不完全了解您打算做什么。通常,如果一个进程被杀死,VM 不会停止,除非您为此编写一些代码(我从未尝试过,但它应该是可行的)。在这种情况下,您应该像@Vinod 所说的那样使用 opion -heart 和 init:reboot 重新启动 VM。
但控制和重启进程的常用方法是在 VM 内使用主管树 .然后,您可以调整重启策略以获得良好的可靠性和良好的服务。同样,正如@Vinod 所说,网站learnyousomeerlang.com 是您的朋友。您将找到编写符合 OTP 的应用程序所需的几乎所有内容。
【讨论】:
以上是关于杀死进程并在erlang中运行程序的主要内容,如果未能解决你的问题,请参考以下文章
在 ProcessPoolExecutor 中杀死进程 [重复]
优雅地杀死在 Linux 上运行的 .NET Core 守护进程