Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
向所有活动线程发送信号(Windows) 我面临一个关于C++、Windows中线程同步的设计问题。p>_C++_Windows_Multithreading_Synchronization - Fatal编程技术网

向所有活动线程发送信号(Windows) 我面临一个关于C++、Windows中线程同步的设计问题。p>

向所有活动线程发送信号(Windows) 我面临一个关于C++、Windows中线程同步的设计问题。p>,c++,windows,multithreading,synchronization,C++,Windows,Multithreading,Synchronization,我正在编写一个服务器应用程序,它启动一个侦听线程,当服务器启动时,该线程应该一直处于活动状态。 当侦听线程收到连接请求时,它打开一个控制套接字并启动一个新的控制线程。 该线程用于在服务器和客户机之间发送控制数据,初始化服务器和所有后台软件到特定的客户机数据,并启动数据处理 如果初始化(通过控制套接字)成功,则控制线程将打开一个新的套接字,即数据套接字,然后用于将数据从服务器传递到客户端。它还将启动两个新线程,一个在这个新的数据套接字上发送,另一个在控制套接字上接收,等待客户端是否要终止连接 当客

我正在编写一个服务器应用程序,它启动一个侦听线程,当服务器启动时,该线程应该一直处于活动状态。 当侦听线程收到连接请求时,它打开一个控制套接字并启动一个新的控制线程。 该线程用于在服务器和客户机之间发送控制数据,初始化服务器和所有后台软件到特定的客户机数据,并启动数据处理

如果初始化(通过控制套接字)成功,则控制线程将打开一个新的套接字,即数据套接字,然后用于将数据从服务器传递到客户端。它还将启动两个新线程,一个在这个新的数据套接字上发送,另一个在控制套接字上接收,等待客户端是否要终止连接

当客户端不正常地终止连接时,通过在不调用发送服务器消息以关闭连接的函数的情况下终止应用程序,应该发生以下情况:

  • 执行中的任何线程都可以检测到此事件。它们在数据/控制套接字上发送或接收数据时会出现某种错误(WSAECONNRESET),然后应向所有其他线程发出停止执行的信号(服务器侦听线程除外)
实现这种行为最自然的方式是什么


(我使用winsock(winsock2.h)进行联网,使用标准windows api(windows.h)进行线程)

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

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

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

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


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

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

看起来您使用了很多线程。欢迎您就如何优雅地更改这些事件发表建设性意见。这是我的第一个多线程应用程序,我不熟悉处理此类问题的常用方法。你能发表一个关于改进原始想法的想法吗?服务器必须能够同时通过数据和控制套接字进行发送。如果我不将其分为两个线程,如何实现这一点?此外,recv和send函数的exibit阻塞行为也是我决定将其分为两个线程的原因,一个是接收,另一个是在套接字上发送。@construction:请参阅WSAWaitForMultipleEvents<如果您已等待“数据可用”事件,则代码>recv不会阻塞。强制关闭所有打开的套接字。这将导致所有阻塞套接字调用返回错误代码,从而允许所有线程退出。与退出main()函数并让CRT终止进程没有太大区别。友好地说再见通常是首选。放弃阻塞插座。使用重叠IO。看见