2014-11-03 33 views
1

我們編寫了利用I/O完成端口的軟件,並在SOCKET對象上使用WSASend,在命名管道上使用WriteFile。IOCP:內核如何決定同步或異步完成WSASend?

在這兩種情況下,我們發現這些API比我們預期的要早得多地返回SOCKET_ERROR/WAS_IO_PENDING [1](或命名管道WriteFile操作的等價物)。

看來我們錯誤地認爲,如果填充發送緩衝區(CreateNamedPipe中的nInBufferSize),會觸發異步完成,相反,它看起來更具侵略性,與發送緩衝區的大小無關。對於套接字和命名管道,如果速度足夠快,則在第二次寫入時,一個大型發送緩衝區(100k +)和小型消息(幾個字節)將始終以異步方式完成。

任何人都可以證實這一點嗎?有沒有人有關於啓發式方面的信息,即Windows實現在決定何時異步完成I/O操作時,與做同步完成時相比?

[1]「如果重疊操作成功啓動並稍後完成,則WSASend返回SOCKET_ERROR並指示錯誤代碼WSA_IO_PENDING。」 - http://msdn.microsoft.com/en-us/library/windows/desktop/ms742203(v=vs.85).aspx

+3

此類實現細節可能會有所變化。你需要確保你的代碼不包含任何關於它們的假設。 – 2014-11-03 02:49:37

回答

1

爲什麼你認爲你需要知道或關心。它不是API的文檔部分,它可能受到當時堆棧中的驅動程序和任何分層服務提供程序的影響。

您必須編寫正確的代碼來處理成功的「同步」發送或待處理的「異步」發送,那麼它會使您得到哪種結果的頻率有多大?

此外,除非您使用SetFileCompletionNotificationModes()來啓用FILE_SKIP_COMPLETION_PORT_ON_SUCCESS,否則同一代碼路徑將用於同步和未決結果。