gpt4 book ai didi

c - 将CompletionRoutine与多个套接字一起使用时,如何从WSARecvFrom()同步处理

转载 作者:行者123 更新时间:2023-12-03 11:51:10 24 4
gpt4 key购买 nike

从MSDN文档中:

The transport providers allow an application to invoke send and receive operations from within the context of the socket I/O completion routine, and guarantee that, for a given socket, I/O completion routines will not be nested. This permits time-sensitive data transmissions to occur entirely within a preemptive context.



在我们的系统中,我们确实有一个线程针对多个套接字调用WSARecvFrom()。该线程有一个CompletionRoutine,用于处理来自WSARecvFrom()互操作的I/O的所有回调。

我们的测试表明,此完成例程的调用类似于中断的触发。在仍从另一个套接字处理完成例程的同时,调用了一个套接字。

我们如何防止在仍在处理来自另一个套接字的输入时不调用此完成例程?

我们可以使用哪些数据处理序列化?

请注意,有数百个套接字接收和发送实时数据。与等待多个对象同步不适用,因为Win32 API最多定义了64个。

我们不能使用Semaphore,因为当新调用旧的正在进行的处理时,它将重新实现,这样就不会实现Semaphore,并且永远不会有新的处理块。

关键部分或互斥锁不是一个选项,因为完成例程回调是在同一线程内进行的,因此CS或互斥锁仍然可以接受,并且不会等到旧的处理完成。

是否有人有想法或更好的方法来串行化(同步)​​数据处理?

最佳答案

如果您再次仔细阅读WSARecvFrom() documentation,它还会显示:

The completion routine follows the same rules as stipulated for Windows file I/O completion routines. The completion routine will not be invoked until the thread is in an alertable wait state such as can occur when the function WSAWaitForMultipleEvents with the fAlertable parameter set to TRUE is invoked.



然后 Alertable I/O documentation声明:

When the thread enters an alertable state, the following events occur:

  1. The kernel checks the thread's APC queue. If the queue contains callback function pointers, the kernel removes the pointer from the queue and sends it to the thread.
  2. The thread executes the callback function.
  3. Steps 1 and 2 are repeated for each pointer remaining in the queue.
  4. When the queue is empty, the thread returns from the function that placed it in an alertable state.


因此,给定线程实际上不可能在彼此之上重叠多个挂起的完成例程,因为该线程以串行方式接收和处理例程。我唯一可以看到的不同之处是,完成例程是否正在做一些事情以使线程进入第二个可警告状态,而先前的可警告状态仍然有效。我不确定Windows在那种情况下会做什么,但是无论如何您都应该避免这样做。

Note there are hundrets of sockets receiving and sending realtime data. Synchronisation with waiting for multiple objects is not applicable as there is a maximum of 64 defined by the Win32 API



WaitForMultipleObjects() documentation告诉您如何解决该限制:

To wait on more than MAXIMUM_WAIT_OBJECTS handles, use one of the following methods:

• Create a thread to wait on MAXIMUM_WAIT_OBJECTS handles, then wait on that thread plus the other handles. Use this technique to break the handles into groups of MAXIMUM_WAIT_OBJECTS.

• Call RegisterWaitForSingleObject to wait on each handle. A wait thread from the thread pool waits on MAXIMUM_WAIT_OBJECTS registered objects and assigns a worker thread after the object is signaled or the time-out interval expires.



无论如何,我都不会在套接字上等待,这不是很有效。只要完成工作安全,使用完成例程就可以了。

否则,我建议您停止使用完成例程,而改为将 I/O Completion Port用作套接字I/O。然后,您可以更好地控制何时将完成结果报告给您,因为您必须自己调用 GetQueuedCompletionStatus()来获取每个I/O操作的结果。您可以有多个套接字与一个IOCP关联,然后有一个小的线程池(通常每个CPU内核一个线程效果最好),所有线程都在该IOCP上调用 GetQueuedCompletionStatus()。这样,您可以并行处理多个I/O结果,因为它们将位于不同的线程上下文中,并且不能在同一线程中相互重叠。但是,这确实意味着您可以在一个线程中执行I/O操作,并且结果可能显示在另一个线程中。只要确保完成处理是线程安全的即可。

关于c - 将CompletionRoutine与多个套接字一起使用时,如何从WSARecvFrom()同步处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24203394/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com