Controlling Process

本文探讨了Erlang中使用gen_tcp模块时遇到的socket控制进程问题。通过实例展示了如何通过设置新的控制进程避免因原进程退出而导致socket关闭的情况。
昨天写测试代码的时候,遇到了一些疑惑,那就是erlang中control process.

在使用gen_tcp进行开发的时候,我们可以通过调用gen_tcp:accept和gen_tcp:connect而产生socket,此时调用所在的process,称为这个socket的control process. control process的生存期控制着socket的生存期,如果control process结束了,那么Socket也会被关闭.要解除这个约束的方法是调用gen_tcp:controlling_process/2, 为Socket设置一个新的control process.

参看erlang-china中a pitfall in passing socket via processes 一文:

在花了大半天“追根究底”之后,发现原因是这样的:“socket 是通过 port 实现的,如果这个 port 的 owner process 退出,那么这个 port 也会关闭”。

让我们在通过一个例子来更深的理解一下:


-module(r3).
-compile(export_all).

start() ->
spawn(r3, start, ["www.erlang.org", 80]).

start(RHost, RPort) ->
io:format("start:pid=~p~n", [self()]),
{ok, Sock} = gen_tcp:connect(RHost, RPort, [list, {packet, 0}, {active, false}, {reuseaddr, true}]),
io:format("start:socket=~p~n", [erlang:port_info(Sock)]),
Test = spawn(r3, test, [Sock]),
%% 注释A: 让Sock的contrl process等待一会,从而允许test process使用Sock进行工作
%%receive
%%after 1000 ->
%% ok
%%end.
%% 注释B: gen_tcp:controlling_process(Sock, Test).

test(Sock) ->
%%注释C: gen_tcp:controlling_process(Sock, self()),
io:format("test:pid=~p~n", [self()]),
io:format("socket=~p~n", [erlang:port_info(Sock)]),
ok = gen_tcp:send(Sock, "GET / HTTP/1.0\r\n\r\n"),
case gen_tcp:recv(Sock, 0) of
{ok, Pack} ->
io:format("recv:ok:~p~n", [Pack]);
Any ->
io:format("recv:~p~n", [Any])
end,
ok = gen_tcp:close(Sock).


上面的几个spwan只是为了测试socket在不同process之间处理的情况,因此上面代码不应该是你写程序参考的代码.

如果没有A,B,C三个注释,那么这个module会运行出错,提示Sock undef, 这就是control process起的坏作用,其退出导致socket被关闭. 让我们一步一步的验证我们的想法吧.

1,如果仅仅去除注释A, 我们的control process在spawn(r3, test, [Sock])后,会等待1秒钟,这样Sock不会随着control process的结束而关闭,因此我们可以获取www.erlang.org的内容

2,如果仅仅去除注释B, 那么我们通过controlling_process/2,将Sock的control process设置为Test,这样我们也可以收到www.erlang.org的内容

3,如果仅仅去除注释C,那么我们几乎不能收到任何内容就出现了错误,因为control process退出的速度要大于Test process启动的速度. 我们也可以通过process间发送消息的方法做到两个线程间的同步,从而确保Test process获取Sock的控制权以后原线程在退出. 动手试验一下吧.
### Gnedin Process 的定义与应用 Gnedin Process 并不是一个广泛使用的标准术语,但在某些特定领域中可能存在与其相关的概念。以下是基于现有知识和引用内容对其可能含义的解释。 #### 可能涉及的内容背景 在统计学和机器学习领域,“Process”通常指代某种随机过程或者算法流程。如果提到 **Gnedin Process**,它可能是某个具体研究方向中的专有名称或者是某位学者提出的理论模型。例如,在概率论中存在一些以个人名字命名的过程(如 Dirichlet 过程),这些过程用于描述复杂的分布特性或生成机制[^3]。 对于训练程序以及优化技术方面,可以联想到深度学习框架下的细节说明部分提及到相关内容:“Details of the training process and optimization techniques.” 显然这里讨论的是如何通过精心设计来提升模型性能的方法论之一[^1]。尽管如此,这并不直接指向所谓的 “Gnedin Process”。 另外一段话提到了不同数据库管理系统之间关于数据分段管理方式的区别及其影响因素。“Segmented” 方法应用于 Druid 和 Pinot 中而 ClickHouse 则采用了更为简单的管理模式;不过这种差异并不会显著改变压缩效率或是查询速度等方面的表现水平[^2]。虽然这段文字主要围绕大数据存储解决方案展开论述,但它间接反映了现代信息系统内部复杂的数据流控制逻辑——而这或许正是理解所谓“Gnedin Process”的切入点所在。 #### 假设性的关联分析 假设我们正在探讨一种新型的数据处理方法,则可以从以下几个角度切入: - 数据分割策略:类似于上述提到的各种 NoSQL 解决方案所采用的技术手段; - 动态调整机制:根据实时反馈不断改进操作参数直至达到最优解; - 资源分配原则:确保在整个计算过程中各环节能够均衡利用硬件资源从而提高整体吞吐量。 下面给出一个简单示例用来演示这类抽象概念的具体实现形式: ```python def gnedin_process(data_stream, threshold=0.8): """ A hypothetical implementation demonstrating a 'Gnedin-like' data processing pipeline. Args: data_stream (list): Input dataset as an iterable object. threshold (float): Parameter controlling decision boundary. Returns: list: Processed output after applying rules defined within function body. """ processed_results = [] cumulative_sum = 0 for item in data_stream: cumulative_sum += item if cumulative_sum >= threshold * sum(data_stream): break return [item for item in data_stream[:len(processed_results)]] example_data = [random.random() for _ in range(10)] print(gnedin_process(example_data)) ``` 此代码片段仅作为示意用途,并不代表实际存在的任何官方版本! --- ### 结语 综上所述,由于缺乏足够的上下文支持,目前尚无法确切界定何谓"Gnedin Process"。然而借助类比推理的方式我们可以推测其大致轮廓应该涵盖了诸如动态规划、自适应调节之类的核心思想要素。希望以上信息对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值