prim_inet:async_accept

本文主要探讨了Erlang中prim_inet:async_accept与gen_tcp:accept的区别。gen_tcp:accept是同步阻塞的,而async_accept是异步非阻塞的,适用于高并发场景。文章分析了内核中的队列、阻塞与非阻塞accept,以及为何需要使用async_accept以避免潜在的连接丢失问题。最后,讨论了多进程同时accept的可能性和惊群问题的解决方案。
摘要由CSDN通过智能技术生成

无意中发现erlang服务器挺多使用prim_inet:async_accept,而不是gen_tcp:accept。查询了下文档和源码,这两个接口的主要区别还是在于同步和异步。async_accept是异步的,而accept是同步的,会一直阻塞到有连接到来才会返回。这里就涉及了很多有意思的概念,tcp accept的过程、同步、异步、阻塞和非阻塞,这篇文章的目的就是简要的记录并理清这些概念。


gen_tcp:accept

Accepts an incoming connection request on a listen socket. Socket must be a socket returned from listen/2. Timeout specifies a timeout value in ms, defaults to infinity.
gen_tcp模块提供的accept接口是一个阻塞的方法,我们需要指定timeout时间或者默认timeout时间为infinity。


prim_inet:async_accept

prim_inet:async_accept是一个非阻塞的异步accept接口。虽然文档上并没有说明该接口,只是在内部调用中使用,但是在rabbitmq等很多服务器的accept实现中都用到了这个异步accept的接口。


accept与async_accept的实现

查看prim_inet模块关于tcp accept的实现,可以发现,其实gen_tcp:accept的实现是基于async_accept的,gen_tcp:accept会一直阻塞在receive中等待消息。而直接调用async_accept的话,进程会在accept socket后收到消息{inet_async,…}。
{inet_async, L, Ref, {ok, S}}, S就是socket了。

%% For TCP sockets only.
%%
accept(L)            -> accept0(L, -1).

prim_mst构造最小生成树的思想是通过贪心算法逐步选择边来构建最小生成树。具体步骤如下: 1. 创建一个空的最小生成树MST和一个空的集合visited,用于存储已经访问过的顶点。 2. 选择一个起始顶点作为根节点,并将其加入visited集合。 3. 从根节点开始,遍历与根节点相邻的边,并选择权重最小的边。 4. 将选择的边加入MST,并将边的另一个顶点加入visited集合。 5. 重复步骤3和步骤4,直到visited集合包含所有顶点。 6. 最终得到的MST就是原图的最小生成树。 以下是使用prim_mst构造最小生成树的示例代码: ```python import numpy as np def prim_mst(graph): num_vertices = len(graph) MST = [] visited = set() # 选择起始顶点 start_vertex = 0 visited.add(start_vertex) while len(visited) < num_vertices: min_weight = np.inf min_edge = None # 遍历已访问的顶点 for vertex in visited: # 遍历与已访问顶点相邻的边 for neighbor, weight in enumerate(graph[vertex]): # 如果边的另一个顶点未访问且权重更小,则更新最小边 if neighbor not in visited and weight < min_weight: min_weight = weight min_edge = (vertex, neighbor) # 将最小边加入MST,并将边的另一个顶点加入visited集合 MST.append(min_edge) visited.add(min_edge[1]) return MST # 示例输入矩阵 graph = np.array([[0, 192, 344, 0, 0, 0, 0, 0, 0, 0, 0], [192, 0, 309, 0, 555, 0, 0, 0, 0, 0, 0], [344, 309, 0, 499, 0, 0, 0, 0, 0, 0, 0], [0, 0, 499, 0, 840, 0, 229, 286, 0, 0, 0], [0, 555, 0, 840, 0, 237, 0, 0, 0, 0, 0]]) # 构造最小生成树 MST = prim_mst(graph) print("Minimum Spanning Tree:") for edge in MST: print(edge) ``` 输出结果为最小生成树的边集合。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值