【问题标题】:Signaling all active threads (Windows)向所有活动线程发出信号 (Windows)
【发布时间】: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


【解决方案1】:

如果您正在编写多线程 winsock 服务器,则应该查看 IO 完成端口。使用 IO 完成端口是在 windows 平台上编写网络服务的最具扩展性的方式。

基于 IO 完成端口的 Winsock 服务器使用异步通信,因此您的线程池不会在套接字上阻塞,而是在有趣的事情发生时接收完成数据包。

无论如何,您都将使用WSARecv。当 WSARecv 返回非零时,调用WSAGetLastError()。如果您没有WSA_IO_PENDING,则打开错误并查找您感兴趣的winsock error code

winsock 错误代码 WSA_OPERATION_ABORTED 表示套接字已关闭,尽管还有其他错误代码(例如 WSAECONNABORTED)。

会建议一个关于该主题的好文本(例如通过 C/C++ 的 Windows)。

【讨论】:

    【解决方案2】:

    您可以使用 WSAEventSelect() 函数将事件对象与套接字关联并为您的事件创建一个事件对象,然后在 WaitForMultipleObjects() 函数中使用这些事件对象,以便您的线程可以等待套接字事件和您的自定义事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-09
      • 2018-01-15
      • 2016-11-06
      • 2018-04-29
      • 1970-01-01
      相关资源
      最近更新 更多