- 浏览: 337709 次
- 性别:
- 来自: 北京
最新评论
-
perfect_control:
真的很详细,一些东西很容易被我忽略掉了
使用fprof进行性能分析 -
leeyisoft:
http://www.erlangqa.com/ 怎么变成 “ ...
Erlang问答网站,欢迎各位提出问题,解答问题。 -
simsunny22:
4年之后我才看到 慢慢的干货
Erlang服务器内存耗尽bug跟踪过程 -
爱死我:
...
使用etop查看系统中进程信息 -
宋兵甲:
在跑这个服务的时候,每秒建立一个客户端连接,连续建立10000 ...
自己写一个tcp 通用服务器
关于io_request
相关module
涉及到kernel/io, kernel/user, kernel/application_master, stdlib/slave.
Erlang中的标准io接口
stdlib/io module, 为erlang中的标准的io接口模块,其io操作基于process实现, 如对文件, 标准输入输出等操作,都可以使用 此module进行处理(对于文件,file:open/2, 默认是使用io模块进行操作,除非指定raw选项).
使用io module具有一些好处:我们可以使用统一的接口对实现io操作; 其他的process也可以 访问被打开的io device; 在分布式环境中,可以进行基于Process Message机制的交互. 至于缺点,毫无疑问,就是可能导致性能下降, 比如对于file的操作,使用raw模式会更快.
关于group leader
一组process,可以组成一个group, 请注意这里的group和kernel中的 pg2, global, global_groupe等没有任何关系.
group leader可以理解成process的一个属性.我们可以通过erlang:process_info/1,可以查看process的group_leader 信息. group_leader对应的value为某个process pid.
每当我们spawn一个新的process时, 其都会继承parent的group_leader属性.
估计很多人会有疑问,group_leader有何作用呢?
process的io module相关的操作, 会转交给group_leader进行处理. 所以group_leader类似一个router, 其接受io module的 io_request请求,然后转发给相应的module进行处理.
对于io这方面的操作,很多语言可能是在运行时的内部进行实现支持. erlang在运行时之上又分离出group_leader这一层, 目的就是在分布式系统中, 我们可以通过重新设置process的group_leader,从而 达到重定向其io流的方向. 这个概念似乎和*unix中的"|", 重定向有点类似.
我们可以使用group_leader,实现分布式系统中, 节点io的重定向, 这样便于我们调试和记录一些信息.
erlang emulator启动时,init作为第一个process(通常编号为<0.0.0>), 是所有process的group_leader.
kenerl lib中user模块, 负责处理具体的io_request, 其可以在erlang shell输出数据, 可以从erlang shell读取数据,因此对于我们 本文所讲述的io_request, user是最顶层的group_leader.
application与group_leader
application创建的时候, 其默认的group_leader为user process, 在application对应的application master中,其设置group leader 为self, 但是app master同时保存原有的group leader即user.
application中所有的process的group leader都指向其的application master. 任意一个process的io request信息都会发送给app master.
注意,前面我们提过, app同时保存了旧的group leader, 在app master的loop中, 我们看到处理代码如下:
IoReq when element(1, IoReq) =:= io_request -> State#state.gleader ! IoReq, init_loop(Pid, Tag, State, Type); ....
其将io request消息,简单的发送给了old group leader, 也就是user. 这里这么做,我猜测可能是为了以后的某些功能.
使用io模块
我们经常调用io:format/1,2,3, 用来显示一些调试及提示信息, 那这个命令执行过程是怎么样的呢?
如果使用io:fromat/1,2, 没有指定io device, 那么default_output即是调用此函数process的group_leader(). 如果此process属于某个application,那么依据前面的知识,我们可以知道,消息的路线如下:
io:fromat/1,2 -> app master (group_leader) -> user
我们也可以使用io:format/3, 通过指定io device为user, 指定目标device. 那么消息的路线如下:
io:format(user, Msg, D) -> user
slave节点的io request
stdlib中的slave module,可以用来启动slave节点, slave module说明中有下面的描述:
All TTY output produced at the slave will be sent back to the master node. File I/O is done via the master.
这里是如何实现的呢?
比如我们的master节点通过ssh启动slave节点, 其参数中,有一个 -master 选项,其设置为master node()(具体参看stdlib/slave.erl), 当远程的slave节点的erlang emulator启动时, user_sup module判断 -master 如果设置, 则不会创建一个新的user process, 其获取master的user pid, 然后注册成本地user name指向master的user pid.
具体代码如下(user_sup.erl):
case get_user() of ... {master, Master} -> Pid = start_slave(Master), {ok, Pid, Pid}; ... start_slave(Master) -> case rpc:call(Master, erlang, whereis, [user]) of User when is_pid(User) -> spawn(?MODULE, relay, [User]); _ -> ... end. relay(Pid) -> register(user, self()), relay1(Pid). relay1(Pid) -> receive X -> Pid ! X, relay1(Pid) end
在relay1的loop中,任何io request及其他消息,只是简单的交给远程的master进行处理.
一个简单的例子
东拉西扯,说了很多东西,可能比较模糊. 让我们举一个简单的例子, 希望可以让你的思路更加清晰.
我们在本地,启动两个node foo, bar, 将Node bar的group leader设置为foo的user, 看看效果:
foo:
erl -sname foo (foo@cheng)1>
bar:
erl -sname bar (bar@cheng)1> net_kernel:connect_node('foo@cheng'). true (bar@cheng)2> [Foo] = nodes(). ['foo@cheng'] (bar@cheng)3> User = rpc:call(Foo, erlang, whereis, [user]). <5268.28.0> (bar@cheng)4> group_leader(User, self()).
此时,在foo的shell发生了变化: foo:
(foo@cheng)1> true
这个就是bar节点上调用group_leader/2的返回值:true.
好了, 现在bar的erlang shell 所在process的group leader已经设置为bar的user process. 让我们调用io module输出一些信息:
bar:
(bar@cheng)5> io:format("hello, i'm ~p~n", [self()]).
foo显示信息:
(foo@cheng)1> hello, i'm <5230.35.0> (foo@cheng)1> ok
其中<5230.35.0>为bar中shell process的pid. 下面的ok,是在bar中调用io:format/2后的输出. 我们在bar中的标准输出,现在已经传输到foo中.
那么有没有什么方法,可以让输出显示在bar中呢? 当然可以!
bar:
(bar@cheng)6> io:format(user, "please show in the bar~n", []). please show in the bar ok
我们通过指定io device为local user, 来使io request显示在本地.
小提示
可以通过设置group leader来实现io request重定向, 在记录日志,调试系统方面具有一定的作用.
一点问题:io reqeust采用request-reponse的方式进行交互, 发送的消息随后会等待应答, 比如调用 io:format返回的ok, 即是应答.
评论
发表评论
-
Erlang问答网站,欢迎各位提出问题,解答问题。
2012-03-18 15:07 5323平时收到很多关于Erlang的问题,我都尽量一一解答,可是时间 ... -
Emakefile并行编译
2011-11-17 13:15 7682项目代码越来越多,使用erlang编译也越来越慢。无论是Mak ... -
Erlang服务器内存耗尽bug跟踪过程
2011-10-25 21:44 21917本文描述朋友Erlang服务器内存耗尽bug的解决过程 ... -
inet:getstat/2小用法
2011-04-27 09:32 4603inet:getstat/2的用处 在 ... -
Erlang游戏开发-协议
2011-04-22 16:10 10745Erlang游戏开发-协议 ... -
Gearman Erlang Client
2010-10-17 21:14 3738Gearman Gearman是一个通用的任务调度框架。 ... -
ECUG归来
2010-10-17 21:02 2996今天ECUG V圆满结束了,不知不觉作为讲师已经参加过3次大会 ... -
gen-erl-app快速生成erlang app 框架
2010-04-07 14:22 4017经常需要创建各种erlang app,这个过程一旦掌握,就很繁 ... -
erl-redis发布
2010-03-30 11:44 5809最近几天因为需要,实现了一个redis erlang clie ... -
用Erlang做了很多事
2010-01-19 14:08 5103因为工作及时间关系,最近比较忙碌,没有太多的时间写文章。 ... -
ecug topic - erlang开发实践
2009-11-11 10:04 3777从ecug归来,感觉不错,大家学习探讨的积极性很高哦。 很高 ... -
reltool用户指南
2009-11-02 22:27 6412说明,最近比较忙,没有太多时间更新blog,请各位朋友谅解. ... -
Erlang定时任务server (仿crontab语法)
2009-09-23 18:03 6400好久不写blog了,看到yufeng老大那么活跃,我也“耐不住 ... -
Erlang进程之错?
2009-07-27 15:06 3709前阵子erlang-china关于erla ... -
CNode指南
2009-07-27 14:13 3365好久不发文章,因为工作太忙。这个东西就凑凑数吧。各位见谅。 ... -
Erlang类型及函数声明规格
2009-06-08 22:41 9592Erlang类型及函数声明 ... -
使用etop查看系统中进程信息
2009-05-29 13:57 6200Erlang提供了丰富的开发工具,你认为没有的时候,很可能是你 ... -
创建gen_server组解决单process瓶颈
2009-05-27 17:05 5299并发和顺序是一个令人 ... -
又有人投入Erlang的怀抱了:37Signals Campfire loves Erlang
2009-05-14 23:00 3698就喜欢看这样的东西... This is so juicy ... -
list random shuffle实现
2009-05-07 13:41 4370在项目中需要对list进行随机shuffle,但是在erlan ...
相关推荐
在Windows驱动开发中,IRP (I/O Request Packet) 和 IO_STACK_LOCATION 是两个至关重要的概念。它们之间存在着密切的关系,通常被视为一个整体来理解。本篇文章旨在深入探讨IRP与IO_STACK_LOCATION之间的联系及其在...
标签“gpio_linux_arm9_gpio_linux io_control.ko_linux下gpio”进一步强调了这是关于Linux系统下的GPIO编程,特别是与ARM9处理器兼容的实现。"io_control.ko"可能是一个关键组件,它允许用户空间程序通过系统调用或...
Linux 下 request_mem_region 的详细解释 Linux 操作系统中,I/O 内存映射列表的管理是通过 request_mem_region 函数来实现的。该函数主要用于申请和管理 I/O 内存区域,以便于设备驱动程序能够正确地访问和操作 I/...
7. ReplicatedPG::do_request(副本请求) 在这个阶段,primary 节点会将操作请求副本节点,副本节点会执行相应的操作。这里的延迟主要来自于网络延迟和副本节点的执行时间。 8. ReplicatedPG::do_op(副本操作) ...
在IT行业中,输入/输出(IO)操作是程序与外部数据交互的基础,无论是读取配置文件、处理用户输入,还是保存程序结果。本项目“io0007-find_progress”显然是一个聚焦于IO实用工具和常见功能模块的代码集合,旨在...
- **消息格式**:客户端与io_server之间的通信基于`io_request`/`io_reply`元组。这些元组包含了必要的信息来描述请求或响应。具体格式如下: - `io_request`通常包含一个请求ID、设备标识符以及请求的具体内容。 ...
SCSI设备的队列初始化是在`scsi_alloc_queue`函数中完成的,其中`q->request_fn`被初始化为`scsi_request_fn`。在创建SCSI设备时(`scsi_add_device`函数),会为每个SCSI设备创建一个队列。这一过程通常从驱动程序...
Public_API_Request.github.io 公开API请求 我也更新了卡片,背景和悬停样式上CSS颜色。
### 宏]_IO, _IOR, _IOW, _IOWR 的用法与解析 #### 一、概述 在Linux系统编程中,尤其是在驱动程序开发领域,宏`_IO`, `_IOR`, `_IOW`, `_IOWR`是非常重要的组成部分。它们主要用于构建 ioctl 命令代码,以便于在...
基本的通信流程包括客户端发送io_request消息到服务器,服务器执行相应的请求操作后,返回一个io_reply消息给客户端。任何io_server都可以与任何客户端代码一起使用,而且客户端代码不需要知道io_server与实际设备...
确保对用户提供的数据进行充分验证和清理,避免SSRF(Server-Side Request Forgery)或RCE(Remote Code Execution)等攻击的发生。 总结来说,`file_put_contents`是一个强大且灵活的函数,但同时也需要谨慎使用,...
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; break; } status = Irp->IoStatus.Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; }
`gpio_to_irq()`函数可将GPIO编号转换为中断号,然后通过`request_irq()`函数注册中断处理程序。中断处理函数会在GPIO状态变化时被调用。 6. "www.pudn.com.txt"可能包含的是关于GPIO驱动的文档或教程,可能涵盖了...
服务通常通过`io_context`对象进行管理,`io_context`是Boost.Asio的核心,它管理了所有异步操作的调度和执行。 ### 4. 容器和辅助工具 Boost.Asio还提供了一些辅助工具,如`strand`用于线程安全,`buffer`类用于...
% npm install socket.io-request -save 方法 request("method", data)返回Promise response("method", handler) 用法 客户端到服务器的请求 客户 var ioreq = require ( "socket.io-request" ) ; var io = require...
2. **request_fn() — host_make_request()**:设备特定的IO请求处理函数。 3. **Mvumi_fire_cmd()**:特定设备的命令处理函数。 4. **__make_request()**:通用的IO请求提交函数。 5. **ext3_readpage()**:用于从...
shelf_buffer_request 用于缓冲请求的架子中间件,以便可以多次读取其主体。用法一个简单的使用示例: main() { Handler handler = const Pipeline() .... io.serve(handler, InternetAddress.ANY_IP_V4, 1234).the
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev) ``` 此函数用于向系统申请指定编号的中断资源。参数`handler`指定中断服务函数,`flags`标志位用于...
分配I/O区域的主要函数是`__request_region()`,它建立在`__request_resource()`之上。这个过程包括以下步骤: 1. 使用`kmalloc()`在内核SLAB分配器中为`resource`结构分配内存。 2. 初始化`resource`结构,如设置...
8、Master实现的功能:包括SMI接口规范、配置管理器(Configuration Manager)、数据存储(DS)、请求数据交换(On-request Data exchange)、诊断单元(Diagnosis Unit)等 9、附录内容 包括:数据编码结构、数据...