首页 > 解决方案 > I/O Completion 端口何时增加/减少多线程设计中每个套接字的 RefCount?

问题描述

我读了这个问题 I/O Completion Ports *LAST* called callback, or: where it's safe to clean up things

我无法解决我的问题。答案并未完全涵盖此方法。我也在这里和谷歌搜索了很多,但找不到解决方案,所以我在这里打开一个问题,希望不要重复。

在多线程 IO Completion 端口设计中何时增加RefCountPer Socket 结构?即CompletionKey. 目前我在调用之前确实增加了它WSARecv,如果调用的返回值不是 0 或ERROR_IO_PENDING最后一个错误,我会减少它并调用一个清理函数,这个函数将检查是否RefCount为 0,如果是则它将释放 Per套接字结构。否则它只会释放 Per IO 结构(OVERLAPPED 之一),我也会在WSASend使用上述相同方式发出任何之前增加它。这RefCount是原子使用CRITCAL_SECTION. 从我回来后,GetQueuedCompletionStatus我也减少了RefCount

但是我对这种方法有一些疑问

我有一个从主线程发送文件的函数,该函数正在读取文件并发出一个通过 IO Worker 线程进行PostQueuedCompletionStatus发送WSASend的函数,该函数以块的形式发送文件,当每个块完成时,IO Worker 线程将通知主线程PostMessage发出下一个块的另一个发送。

现在我应该在哪里增加这个RefCount?在发出调用之前在主线程中PostQueuedCompletionStatus?但是如果从返回的GetQueuedCompletionStatus返回并释放 Per Socket 结构并且主线程仍在使用它怎么办?(例如主线程正在执行发送函数但尚未增加RefCount)我试图增加IO Worker 线程RefCount中的WSASend函数但这是同样的问题

例如:如果一个线程从GetQueuedCompletionStatus一个套接字闭包中唤醒(由未完成的 引起WSARecv)并减少RefCount并且它变为 0 ,因此它将释放 Per Socket 结构,而 aWSASend在另一个 IO Worker 线程中执行但尚未增加RefCount?那么很明显,即将发出WSASend调用的线程在尝试进入临界区时都会因访问冲突而崩溃。

知道如何在 IO Worker 线程和主线程之间同步对该结构的访问吗?

标签: windowsmultithreadingsocketsatomiciocp

解决方案


推荐阅读