【发布时间】:2012-04-19 18:01:00
【问题描述】:
我正在尝试实现一个基于 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 的更新不会很频繁,所以我需要避免使用请求-回复模式。
我对实现的初步考虑是,在主线程(监听线程)中维护 ctrl_sock,在另一个线程(工作线程)中维护data_sock 上的传输。但是,我发现在这种情况下很难同步。例如,如果我在peers_context 中使用互斥锁,那么每当工作线程锁定peers_context 时,当需要修改peers_context 时,侦听线程将无法再访问它,因为工作线程无休止地工作。另一方面,如果侦听器线程持有peers_context 并对其进行写入,则工作线程将无法读取peers_context 并终止。谁能给我一些建议?
顺便说一下,实现是在Linux环境下用C语言完成的。只有监听线程偶尔需要修改peers_context,工作线程只需要读取。衷心感谢!
【问题讨论】:
-
为什么不使用 TCP?您可以与每个客户端建立基于流的连接并执行必要的通信,而无需担心同步。比 UDP 更简单、更可靠。
-
听起来您只需要稍微复杂一点的锁定。显然你不能让工人无休止地持有锁。你需要加锁、发包、解锁
-
是否可以/希望使用 select() 或 poll() 将其重新编码为状态机?这可能比线程设计执行得更好,并且避免了所有那些恼人的线程同步问题!
-
@Raam 这是我研究中的模拟工作,没有考虑TCP流量模型。传输的可靠性由应用层保证。
-
嗨,@SimonElliott,使用 select() 看起来是个好主意。我会研究一下,谢谢指出。
标签: c multithreading sockets process