【发布时间】:2011-08-05 11:42:33
【问题描述】:
我遇到了有关 C++、Windows 中线程同步的设计问题。
我正在编写一个启动一个监听线程的服务器应用程序,该线程应该在服务器启动时始终保持活动状态。 当监听线程收到 connect 请求时,它会打开一个 CONTROL 套接字并启动一个新的 control 线程。 该线程用于在服务器和客户端之间发送控制数据,将服务器和所有后台软件初始化为特定的客户端数据并开始数据处理。
如果初始化(通过控制套接字)成功,控制线程将打开一个新的套接字,数据套接字,然后用于将数据从服务器传递到客户端。它还将启动两个新线程,一个在这个新的 DATA 套接字上发送,另一个在 CONTROL 套接字上接收,等待客户端是否要终止连接。
当客户端不正常地终止连接时,通过终止应用程序而不调用发送服务器消息以关闭连接的函数,应该发生以下情况:
- 任何正在执行的线程都可以检测到此事件。它们在 DATA/CONTROL 套接字上发送或接收时会收到某种错误 (WSAECONNRESET),然后应该向所有其他线程发出信号,告知它们应该停止执行(服务器侦听线程除外)。
实现这种行为最自然的方式是什么?
(我使用 winsock (winsock2.h) 进行联网,使用标准 windows api (windows.h) 进行线程)
【问题讨论】:
-
看来你使用了很多线程。
-
欢迎任何关于如何优雅地改变它的建设性评论。这是我的第一个多线程应用程序,我不熟悉处理这类问题的常用方法。你能发表一个关于改进原始想法的想法吗?服务器必须能够同时通过数据和控制套接字发送。如果我不将其分成 2 个线程,我该如何实现?此外,recv 和 send 函数表现出阻塞行为,这就是为什么我决定将它分成两个线程 - 一个接收,另一个在套接字上发送。
-
@construKction:参见 WSAWaitForMultipleEvents。如果您已经等待“数据可用”事件,
recv不会阻塞。 -
强制关闭所有打开的套接字。这将导致所有阻塞套接字调用返回错误代码,从而允许所有线程退出。与仅让您的 main() 函数退出并让 CRT 终止进程没有太大区别。和蔼地说再见通常是首选。
-
放弃阻塞套接字。使用重叠 IO。见tangentsoft.net/wskfaq/articles/io-strategies.html
标签: c++ windows multithreading synchronization