我正在尝试为Erlang编写Golang驱动程序,可通过Erlang端口访问.
我开始使用Erlang C端口示例,它工作正常:
http://www.erlang.org/doc/tutorial/c_port.html
现在我正在尝试将C代码移植到Golang; 只是尝试回显一个简单的'Hello World \n'消息,使用'\n'作为分隔符.
所以我的Golang代码如下:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter text: ")
bytes, _ := reader.ReadBytes('\n')
os.Stdout.Write(bytes)
}
Run Code Online (Sandbox Code Playgroud)
我可以编译它并从命令行运行它,如下所示:
justin@justin-ThinkPad-X240:~/work/erlang_golang_port$ go build -o tmp/echo echo.go
justin@justin-ThinkPad-X240:~/work/erlang_golang_port$ ./tmp/echo
Enter text: hello
hello
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试从Erlang端调用驱动程序时(下面的Erlang代码),我得到以下内容:
justin@justin-ThinkPad-X240:~/work/erlang_golang_port$ erl
Erlang R16B03 (erts-5.10.4) [source] [64-bit] [smp:4:4] [async-threads:10] [kernel-poll:false]
Eshell V5.10.4 (abort with ^G)
1> c(complex1).
{ok,complex1}
2> complex1:start("./tmp/echo").
<0.41.0>
3> complex1:ping().
=ERROR REPORT==== 23-Apr-2015::08:56:47 ===
Bad value on output port './tmp/echo'
Run Code Online (Sandbox Code Playgroud)
我感觉消息正在传递给驱动程序,但我以某种方式错误地返回响应. …
免责声明:该问题的作者具有Erlang的平均知识和C的基本知识.
我现在正在阅读互操作性教程用户指南.我已经成功编译了这个complex.c例子,它与Erlang Port一起使用没有任何问题.
但是,我想了解实际的C代码是如何工作的.我一般都理解它:在示例中,它从标准输入读取2个字节并检查第一个字节.取决于它调用的第一个字节foo或bar函数.这是我现在对它的理解的极限.
所以,如果我们同时采取两个erl_comm.c:
/* erl_comm.c */
typedef unsigned char byte;
read_cmd(byte *buf)
{
int len;
if (read_exact(buf, 2) != 2)
return(-1);
len = (buf[0] << 8) | buf[1];
return read_exact(buf, len);
}
write_cmd(byte *buf, int len)
{
byte li;
li = (len >> 8) & 0xff;
write_exact(&li, 1);
li = len & 0xff;
write_exact(&li, 1);
return write_exact(buf, len);
}
read_exact(byte *buf, int len)
{
int i, got=0;
do …Run Code Online (Sandbox Code Playgroud) 我正在使用RabbitMQ.出于某种原因,RabbitMQ服务会在您启动后立即停止.我在事件日志中看到以下错误:
RabbitMQ: Erlang machine stopped instantly (distribution name conflict?). The service is not restarted as OnFail is set to ignore.
Run Code Online (Sandbox Code Playgroud)
有人告诉我运行这个命令: erl -sname rabbit
此命令生成以下输出:
{(no error logger present")i neirtr otre: r"mEirnraotri nign ipnr odcoe_sbso o<
t0".,2{.b0a>d awrigt,h[ {eexrilt_p rviaml_uleo:a d{ebra,dcahregc,k[_{feirlle__pr
reismu_llto,a3d,e[r{,fcihleec,k"_efrill_e_prreismu_llto,a3d,e[r{.feirlle",}\,"{e
lriln_ep,r29i3m}_]l}o,a{dienri.te,rgle\t"_}b,o{olti,n1e,,[2{9f3i}l]e},,"{iinniit
t.,egrelt"_}b,o{olti,n1e,,[78{9f}i]l}e,,{\i"niinti,tg.eetr_lb\o"o}t,,{2l,i[n{ef,
i7l8e9,}"]i}n,i{ti.neirtl,"g}e,t{_lbionoet,,7762},][}{,f{iilnei,t\,"dion_ibto.oe
tr,l3\,"[}{,f{illien,e",i77n6i}t].}e,r{li"n}i,t{,ldion_eb,o74o3t},]3},][}{}f
ile,\"init.erl\"},{line,743}]}]}\n"
Run Code Online (Sandbox Code Playgroud)
我不知道如何解释这个输出.我想知道这个错误是针对RabbitMQ或erlang的.
我不知道如何进行.请建议.
当拥有生成端口的进程死亡并由主管重新启动时会发生什么?
有没有办法让旧港口不与其所有者一起死亡,让新主人"接管"?
如果失败了,是否有可能确保当端口死亡时生成的进程终止?
Francesco Cesarini 的《Erlang 编程》一书提供了一个很好且易于上手的示例,将 Erlang 连接到 Ruby(通过端口实现):
module(test.erl).
compile(export_all).
test() ->
Cmd = "ruby echoFac.rb",
Port = open_port({spawn, Cmd}, [{packet, 4}, use_stdio, exit_status, binary]),
Payload = term_to_binary({fac, list_to_binary(integer_to_list(23))}),
port_command(Port, Payload),
receive
{Port, {data, Data}} ->
{result, Text} = binary_to_term(Data),
Blah = binary_to_list(Text),
io:format("~p~n", [Blah])
end.
Run Code Online (Sandbox Code Playgroud)
但是,本示例中使用的 Ruby 代码使用 Erlictricity 库,该库为程序员完成所有低级操作:
require 'rubygems'
require 'erlectricity'
require 'stringio'
def fac n
if (n<=0) then 1 else n*(fac (n-1)) end
end
receive do |f|
f.when(:fac, String) do |text|
n = text.to_i
f.send!(:result, "#{n}!=#{(fac …Run Code Online (Sandbox Code Playgroud) 我目前正在运行一个通过Nifs运行C代码的Erlang应用程序.但是,如果在C代码中发生分段故障,整个节点将关闭,以及运行Erlang应用程序的Erlang虚拟机.
如果虚拟机死机,监控Erlang应用程序并重新启动它的最佳方法是什么?
嗨,我是Erlang的新蜜蜂,但设法创建一个简单的TCP服务器,接受被动模式的客户端并显示消息.每次新客户端连接到服务器时,我都会生成一个新进程.有没有办法可以使用客户端连接时生成的进程向客户端发送消息.
这是代码.
-module(test).
-export([startserver/0]).
startserver()->
{ok, ListenSocket}=gen_tcp:listen(1235,[binary,{active, false}]),
connect(ListenSocket).
connect(ListenSocket)->
{ok, UserSocket}=gen_tcp:accept(ListenSocket),
Pid=spawn(? MODULE, user,[UserSocket]),
gen_tcp:controlling_process(UserSocket, Pid),
connect(ListenSocket).
user(UserSocket)->
case gen_tcp:recv(UserSocket, 0) of.
{ok, Binary}->% Send basic message.
{error, closed}->% operation on close.
end.
Run Code Online (Sandbox Code Playgroud)
如果我这样做,我可以做些什么.
Pid!{"Some Message"}.并且消息被发送到与非阻塞io的进程相关联的套接字,
免责声明:这个问题的作者主要具有 Erlang/OTP 的理论知识。
我有一个小型 OTP 应用程序,它myapp/ebin通过open_port(). 当我运行应用程序本身时,一切顺利,可执行文件的端口已成功打开。
但是,当我尝试为应用程序运行单元测试时,依赖于失败的单元测试open_port(),因为当启动EUnit应用程序时尝试在myapp/.eunit/ebin.
如何在不更改应用程序本身的代码的情况下更改该行为?如何使用与运行应用程序本身相同的当前目录来运行 EUnit 测试?(我的意思是,为了能够运行 EUnit 而更改提供可执行文件路径的代码并不是一个好主意)。
编辑:我遵循了 Erlang邮件列表中的建议,但code:priv_dir(myapp_name)返回了{error, bad_name}。
编辑:我可以看到.eunit/包含modulename.beam文件并且ebin/包含modulename.beam文件和modulename_tests.beam文件。现在我完全迷失了。当我运行时make test,rebar运行eunit命令,该命令调用目录modulename_tests.beam中的每个文件,该文件调用目录中的ebin/相应文件(清楚地显示文件是在测试期间执行的)。为什么会这样呢?为什么我们需要从目录运行文件而不是?modulename.beam.eunit/filename:absname("")modulename.beam.eunit/modulename.beam.eunit/ebin/
myapp/ebin为什么我们实际上需要在和中拥有完全相同的 .beam 文件myapp/.eunit/ebin?
PS我看了官方文档,没有找到解决办法。
当我有一个Erlang进程ID时,可以使用pid/3或list_to_pid/1函数(内部做同样的事情)来获得用于调试目的的进程。
Process = pid(0,4,1).
Process = list_to_pid("<0.4.1>").
Run Code Online (Sandbox Code Playgroud)
所以问题是;那港口呢?
有很多功能接口可以接受process()和port()数据类型,例如register/2。因此,我需要知道是否有一种方法可以通过#Port<0.567>进程的ID(例如)来获取端口。禁止吗?如果是这样,有什么理由吗?
我按照文档但不明白尝试捕获,有人可以用一个简单的例子解释一下吗?
erlang ×11
erlang-ports ×11
c ×4
erlang-shell ×3
c++ ×2
erlang-otp ×1
eunit ×1
go ×1
rabbitmq ×1
riak ×1
stdin ×1
stdout ×1