我试图实现一个基于UDP的服务器,它维护两个插座,一个用于控制(ctrl_sock
),另一个用于数据传输(data_sock
)。事情是,ctrl_sock
总是上行链路,data_sock
是下行链路。也就是说,客户端将通过ctrl_sock
请求数据传输/停止,数据将通过data_sock
发送给他们。在两个插座之间共享信息
现在的问题是,由于模型没有连接,服务器将不得不维护已注册客户信息的列表(我称之为peers_context
),以便它可以“盲目地”向他们推送数据,直到他们询问停止。在此盲传期间,客户端可能会异步通过ctrl_sock
向服务器发送控制消息。除了初始请求和停止之外,这些信息也可以是例如文件部分的偏好。因此,peers_context
必须异步更新。然而,通过data_sock
的传输依赖于这个peers_context
结构,因此引起了ctrl_sock
和data_sock
之间的同步问题。我的问题是,我能做些什么来安全地维护这两个袜子和peers_context
结构,这样异步更新peers_context
不会造成严重破坏。顺便说一下,peers_context
的更新不会很频繁,这就是为什么我需要避免请求 - 回复模型。
我最初考虑的实现是在主线程(listener线程)中维护ctrl_sock,并且在另一个线程(工作线程)中维护通过data_sock
进行的传输。但是,我发现在这种情况下很难同步。例如,如果我在peers_context
中使用互斥锁,每当工作线程锁定peers_context
时,由于工作线程无休止地工作,侦听线程在它需要修改peers_context
时不再有权访问它。另一方面,如果侦听器线程持有peers_context
并写入它,工作线程将无法读取peers_context
并终止。有人可以给我一些建议吗?
顺便说一下,这个实现是在C语言的Linux环境下完成的。只有监听线程偶尔需要修改peers_context
,工作线程只需要读取。衷心感谢!
为什么不使用TCP?您可以与每个客户端建立基于流的连接,并执行必要的通信,而不用担心同步它。比UDP更容易,更可靠。 – Raam 2012-04-19 18:06:42
听起来像你只需要稍微复杂的锁定。显然你不能让工人无休止地锁住。您需要锁定,发送数据包,解锁 – TJD 2012-04-19 18:10:04
使用select()或poll()将这个状态机重新编码为状态机是否可能/合意?这可能比一个线程化设计更好,并且避免了所有这些刺激的线程同步问题! – 2012-04-19 18:19:53