WSA_WAIT_EVENT_0 在重叠 IO 中的目的是什么?
What is the purpose of WSA_WAIT_EVENT_0 in overlapped IO?
我在网络方面的所有经验都来自 linux,所以我绝对是 windows 网络的初学者。这可能是一个愚蠢的问题,但我似乎无法在任何地方找到答案。考虑以下代码片段:
DWORD Index = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE);
WSAResetEvent( EventArray[Index - WSA_WAIT_EVENT_0]);
每次从 EventArray 中选择一个事件时,WSA_WAIT_EVENT_0
都会从索引中减去,但 WSA_WAIT_EVENT_0
在 winsock2.h
中定义为等于零。
为什么代码会被这种看似不必要的减法弄得乱七八糟?显然编译器会优化它但仍然不明白为什么它在那里。
The documentation 表示如果事件 0 发出信号,它将 return WSA_WAIT_EVENT_0
,如果事件 1 发出信号,WSA_WAIT_EVENT_0 + 1
,依此类推。
当然,他们在 Windows 的这个版本中将 WSA_WAIT_EVENT_0
设置为 0
,但是如果在下一个版本中设置为 1,或者 100 怎么办?
WSA_WAIT_EVENT_0
被定义为 0 的事实 无关 (它只是 WAIT_OBJECT_0
来自 WaitFor(Single|Multiple)Object(s)()
API,也定义为 0 - WSAWaitForMultipleEvents()
本身只是 WaitForMultipleObjectsEx()
的包装器,尽管 Microsoft 保留在未来不破坏现有用户代码的情况下更改实现的权利)。
WSAWaitForMultipleEvents()
一次可以对多个事件进行操作,其return值将是以下可能之一:
WSA_WAIT_EVENT_0 .. (WSA_WAIT_EVENT_0 + cEvents - 1)
特定事件对象已发出信号。
WSA_WAIT_IO_COMPLETION
执行了一个或多个可警告的 I/O 完成例程。
WSA_WAIT_TIMEOUT
发生超时。
WSA_WAIT_FAILED
函数失败。
通常,代码应该查看 return 值并采取相应的行动,例如:
DWORD ReturnValue = WSAWaitForMultipleEvents(...);
if ((ReturnValue >= WSA_WAIT_EVENT_0) && (ReturnValue < (WSA_WAIT_EVENT_0 + EventTotal))
{
DWORD Index = ReturnValue - WSA_WAIT_EVENT_0;
// handle event at Index as needed...
}
else if (ReturnValue == WSA_WAIT_IO_COMPLETION)
{
// handle I/O as needed...
}
else if (RetunValue == WSA_WAIT_TIMEOUT)
{
// handle timeout as needed...
}
else
{
// handle error as needed...
}
考虑到 bAlertable
是 FALSE
(不能调用 I/O 例程)并且 dwTimeout
是 WSA_INFINITE
(不能超时可以过去),因此只有 2 种可能的结果 - 发出事件信号或发生错误:
DWORD ReturnValue = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE);
if (ReturnValue != WSA_WAIT_FAILED)
{
DWORD Index = ReturnValue - WSA_WAIT_EVENT_0;
WSAResetEvent(EventArray[Index]);
}
else
{
// handle error as needed...
}
我在网络方面的所有经验都来自 linux,所以我绝对是 windows 网络的初学者。这可能是一个愚蠢的问题,但我似乎无法在任何地方找到答案。考虑以下代码片段:
DWORD Index = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE);
WSAResetEvent( EventArray[Index - WSA_WAIT_EVENT_0]);
每次从 EventArray 中选择一个事件时,WSA_WAIT_EVENT_0
都会从索引中减去,但 WSA_WAIT_EVENT_0
在 winsock2.h
中定义为等于零。
为什么代码会被这种看似不必要的减法弄得乱七八糟?显然编译器会优化它但仍然不明白为什么它在那里。
The documentation 表示如果事件 0 发出信号,它将 return WSA_WAIT_EVENT_0
,如果事件 1 发出信号,WSA_WAIT_EVENT_0 + 1
,依此类推。
当然,他们在 Windows 的这个版本中将 WSA_WAIT_EVENT_0
设置为 0
,但是如果在下一个版本中设置为 1,或者 100 怎么办?
WSA_WAIT_EVENT_0
被定义为 0 的事实 无关 (它只是 WAIT_OBJECT_0
来自 WaitFor(Single|Multiple)Object(s)()
API,也定义为 0 - WSAWaitForMultipleEvents()
本身只是 WaitForMultipleObjectsEx()
的包装器,尽管 Microsoft 保留在未来不破坏现有用户代码的情况下更改实现的权利)。
WSAWaitForMultipleEvents()
一次可以对多个事件进行操作,其return值将是以下可能之一:
WSA_WAIT_EVENT_0 .. (WSA_WAIT_EVENT_0 + cEvents - 1)
特定事件对象已发出信号。
WSA_WAIT_IO_COMPLETION
执行了一个或多个可警告的 I/O 完成例程。
WSA_WAIT_TIMEOUT
发生超时。
WSA_WAIT_FAILED
函数失败。
通常,代码应该查看 return 值并采取相应的行动,例如:
DWORD ReturnValue = WSAWaitForMultipleEvents(...);
if ((ReturnValue >= WSA_WAIT_EVENT_0) && (ReturnValue < (WSA_WAIT_EVENT_0 + EventTotal))
{
DWORD Index = ReturnValue - WSA_WAIT_EVENT_0;
// handle event at Index as needed...
}
else if (ReturnValue == WSA_WAIT_IO_COMPLETION)
{
// handle I/O as needed...
}
else if (RetunValue == WSA_WAIT_TIMEOUT)
{
// handle timeout as needed...
}
else
{
// handle error as needed...
}
考虑到 bAlertable
是 FALSE
(不能调用 I/O 例程)并且 dwTimeout
是 WSA_INFINITE
(不能超时可以过去),因此只有 2 种可能的结果 - 发出事件信号或发生错误:
DWORD ReturnValue = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE);
if (ReturnValue != WSA_WAIT_FAILED)
{
DWORD Index = ReturnValue - WSA_WAIT_EVENT_0;
WSAResetEvent(EventArray[Index]);
}
else
{
// handle error as needed...
}