为了避免与port进程的通信受一些printf调试信息的影响,通常都要关闭或者替换标准输入输出。
Unix平台下,open_port只要指定nouse_stdio参数就可以让port进程使用fd 3、4作为通信信道,
而在Windows平台下并没有所谓的3、4 fd可用,调用fdopen(3,“rb”)将会出错,这时可以使用
dup和dup2手动进行替换,例子如下:
port测试进程C代码
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <io.h>
#include <fcntl.h>
#include <windows.h>
int main(int argc, char* argv[])
{
//复制stdio fd,之后我们将使用复制的句柄与Erlang通信
FILE* f0 = fdopen(dup(0),"rb");
FILE* f1 = fdopen(dup(1),"wb");
//Windows下默认为Text模式,按需要设置为BINARY模式,
//否则\n将会被替换为\r\n,这通常不是我们想要的
_setmode (_fileno(f0), _O_BINARY);
_setmode (_fileno(f1), _O_BINARY);
//用一个临时文件替换stdio,并关闭之
FILE* ftmp = tmpfile();
dup2(fileno(ftmp), 0);
dup2(fileno(ftmp), 1);
fclose(stdin);
fclose(stdout);
fclose(ftmp);
//测试一些输出
fwrite("hello",1,5,f1);
fputc(' ',f1);
fflush(f1);
printf("world");
fflush(stdout);
std::cout << "!!!!!\n";
std::cout.flush();
Sleep(5000);
return 0;
}
测试用erlang代码:
-module(test).
-compile(export_all).
start() ->
P = open_port({spawn, "./Debug/teststdio.exe"},[binary]),
loop(P).
loop(P) ->
receive
{P, {data, Data}} ->
io:format("~p~n",[Data]),
loop(P)
after 3000 ->
timeout
end.
测试结果:
1、替换stdio后:
Eshell V5.7.5 (abort with ^G)
1> c(test.erl).
{ok,test}
2> test:start().
<<"hello ">>
timeout
3>
2、如果没有替换stdio,将会收到
test:start().
<<"hello ">>
<<"world">>
<<"!!!!!\r\n">>
timeout
我们调用第三方库时很难确认是否会有stdio输出,这种方式很好的避免了printf信息对port通信的影响
注意没有替换stdio部分的输出,stdin和stdout没有指定BINARY模式,\n被替换成\r\n了,
再看看前面dup2部分的调用,虽然指定了"rb"和"wb",但这样是无效的,必须手动调用setmode进行设置才会有效
最后说说windows下使用异步stdio的注意点,需要2个设置:
1、在open_port中指定overlapped_io参数
2、用_get_osfhandle函数得到替换后的io的HANDLE,以供ReadFile和WriteFile操作:
HANDLE hin = (HANDLE)_get_osfhandle(_fileno(f0));
HANDLE hout= (HANDLE)_get_osfhandle(_fileno(f1));
在C程序里使用异步io虽然麻烦,但有时候却是必须的。比如windows系统下通过port访问串行口时,如果不使用overlapped模式,读取串口与读取stdio是不能同时进行的。
分享到:
相关推荐
erlang port driver test vs project. can run on linux
Erlang的windows版本Erlang的windows版本Erlang的windows版本Erlang的windows版本Erlang的windows版本Erlang的windows版本Erlang的windows版本Erlang的windows版本Erlang的windows版本Erlang的windows版本Erlang的...
erlang25.0 windows版本
RabbitMQ version Minimum required Erlang/OTP Maximum supported Erlang/OTP Notes 3.13.0 26.0 26.2.x The 3.13 release series is compatible wtih Erlang 26. OpenSSL 3 support in Erlang is considered to ...
Erlang进程模型特点 一个进程可以创建数以万计的轻量级进程 每个轻量级进程仅仅完成单一功能 一个复杂的功能可以由多个轻量级进程协同完成 当遇到file或socket等阻塞的io时, 调用的轻量级进程被阻塞,整个进程不...
个人学习使用 Erlang是25.0+版本 RabbitMQ 是rabbitmq-server-3.11.9版本
如题,RabbitMQ 3.8.9 windows安装包,以及运行环境erlang的安装包。 先安装erlang,设置环境变量“ERLANG_HOME={erlang安装路径}”,添加“%ERLANG_HOME%\bin”到系统变量Path中 再安装RabbitMQ 再到RabbitMQ安装...
Erlang 里面的函数是数学里面的函数:必须有返回值。 只要是函数必然有返回值,函数是一个过程,以英文的句号为函数结束符。 函数结束之前的表达式就是该函数的返回值。 所以这也是在 Erlang 里面的函数不会看到任何...
关于erlang并发开发的一些例子,便于学习supersivor
This guide covers Erlang/OTP requirements, recommendations, caveats and commonly used installation sources. Unsupported Versions Erlang/OTP versions older than 19.3 are not supported by currently ...
windows系统安装erlang21.1-64 主要用于windows系统安装rabbitmq
Windows下使用NIF扩展Erlang完整例子,包含nif工程项目,erlang引用例子。 配套文章:http://blog.csdn.net/mycwq/article/details/17527485
个人学习使用 Erlang是otp_win64_24.0版本 RabbitMQ 是rabbitmq-server-3.8.16版本
esl-erlang_23.0和rabbitmq-3.8.4windows版本 直接下载安装就行,可以直接下载就可安装,非常的方便 ,欢迎大家下载 注意事项: 1. Erlang版本和RabbitMQ版本要配套 (Erlang23.0, RabbitMQ3.8.4) 2. amd芯片请乖乖...
EPMDPXY - Erlang 端口映射器守护进程的代理 EPMDPXY 模拟了 EPMD 的基本功能,足以让本地 Erlang 集群工作。 但有一个例外,它在处理PORT_PLEASE2_REQ时不是回复侦听器端口,而是生成一个内部侦听器并回复新的...
erlang otp25 win安装包
Erlang官网下载地址非常慢。这是windows 64位 v22.0 安装包,包含esl-erlang_22.0_windows_amd64.exe
总结来说,`os:cmd/1`适合执行简单命令并获取标准输出,而`erlang:open_port/2`则适用于更复杂的场景,如需要错误信息、退出状态码或者控制进程交互。选择哪种方法取决于你的具体需求和对性能的影响。
erlang23.2版windows64位
Erlang分布是一种连续概率分布,常用于描述一系列独立同分布的指数随机变量之和,例如呼叫中心等待时间、服务时间等。在MATLAB中,我们可以利用不同的函数或技巧来生成服从Erlang分布的随机数。以下是两种常用的方法...