如何为句柄重新注册 IO 完成端口
How to reregister for IO Completion ports for a handle
我有一个使用 CreateFile
创建的 Windows 命名管道(服务器端是使用 CreateNamedPipe
创建的)。我使用 IO 完成端口在两端异步地 read/write 数据。
我需要在打开这些句柄后将它们发送给其他进程。我尝试在从 CreateIoCompletionPort
返回的句柄上调用 CloseHandle
,然后在另一个进程中再次调用 CreateIoCompletionPort
。但是它总是失败并且 GetLastError
returns 87 (ERROR_INVALID_PARAMETER
).
我也可以在一个过程中重现这一点,见下文。请注意,在我发送对象之前没有未完成的 reads/write。
std::wstring pipe_name = L"\\.\pipe\test.12345";
HANDLE server = CreateNamedPipeW(
pipe_name.c_str(),
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
1,
4096,
4096,
10000,
NULL);
SECURITY_ATTRIBUTES security_attributes = {
sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
HANDLE client = CreateFileW(
pipe_name.c_str(), GENERIC_READ | GENERIC_WRITE,
0,
&security_attributes,
OPEN_EXISTING,
SECURITY_SQOS_PRESENT | SECURITY_ANONYMOUS | FILE_FLAG_OVERLAPPED,
NULL);
ULONG_PTR key = 1;
HANDLE comp_port = CreateIoCompletionPort(client, NULL, key, 1);
BOOL b1 = CloseHandle(comp_port);
comp_port = CreateIoCompletionPort(client, NULL, key, 1);
if (comp_port == NULL) {
int last_err = GetLastError();
}
CreateIoCompletionPort 的文档表明您无法完成您想要完成的任务。与 I/O 完成端口关联的所有句柄都引用该端口,只要一个端口仍然打开,该端口就会保持活动状态:
The I/O completion port handle and every file handle associated with that particular I/O completion port are known as references to the I/O completion port. The I/O completion port is released when there are no more references to it. Therefore, all of these handles must be properly closed to release the I/O completion port and its associated system resources. After these conditions are satisfied, close the I/O completion port handle by calling the CloseHandle function.
如果您使用 CreateFile 创建一个与 I/O 完成端口无关的新句柄,然后使用 DuplicateHandle 将其传递给其他进程,它应该可以工作。或者直接调用其他进程中的CreateFile
参考documentation for CreateIoCompletionPort:
A handle can be associated with only one I/O completion port, and after the association is made, the handle remains associated with that I/O completion port until it [the handle] is closed.
[...] The I/O completion port handle and every file handle associated with that particular I/O completion port are known as references to the I/O completion port. The I/O completion port is released when there are no more references to it.
换句话说,关闭 I/O 完成端口句柄没有任何作用。 I/O 完成端口仍然存在并且与管道句柄永久关联。您所尝试的根本不可能;您将需要重新架构。
另请注意:
It is best not to share a file handle associated with an I/O completion port by using either handle inheritance or a call to the DuplicateHandle function. Operations performed with such duplicate handles generate completion notifications. Careful consideration is advised.
我有一个使用 CreateFile
创建的 Windows 命名管道(服务器端是使用 CreateNamedPipe
创建的)。我使用 IO 完成端口在两端异步地 read/write 数据。
我需要在打开这些句柄后将它们发送给其他进程。我尝试在从 CreateIoCompletionPort
返回的句柄上调用 CloseHandle
,然后在另一个进程中再次调用 CreateIoCompletionPort
。但是它总是失败并且 GetLastError
returns 87 (ERROR_INVALID_PARAMETER
).
我也可以在一个过程中重现这一点,见下文。请注意,在我发送对象之前没有未完成的 reads/write。
std::wstring pipe_name = L"\\.\pipe\test.12345";
HANDLE server = CreateNamedPipeW(
pipe_name.c_str(),
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
1,
4096,
4096,
10000,
NULL);
SECURITY_ATTRIBUTES security_attributes = {
sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
HANDLE client = CreateFileW(
pipe_name.c_str(), GENERIC_READ | GENERIC_WRITE,
0,
&security_attributes,
OPEN_EXISTING,
SECURITY_SQOS_PRESENT | SECURITY_ANONYMOUS | FILE_FLAG_OVERLAPPED,
NULL);
ULONG_PTR key = 1;
HANDLE comp_port = CreateIoCompletionPort(client, NULL, key, 1);
BOOL b1 = CloseHandle(comp_port);
comp_port = CreateIoCompletionPort(client, NULL, key, 1);
if (comp_port == NULL) {
int last_err = GetLastError();
}
CreateIoCompletionPort 的文档表明您无法完成您想要完成的任务。与 I/O 完成端口关联的所有句柄都引用该端口,只要一个端口仍然打开,该端口就会保持活动状态:
The I/O completion port handle and every file handle associated with that particular I/O completion port are known as references to the I/O completion port. The I/O completion port is released when there are no more references to it. Therefore, all of these handles must be properly closed to release the I/O completion port and its associated system resources. After these conditions are satisfied, close the I/O completion port handle by calling the CloseHandle function.
如果您使用 CreateFile 创建一个与 I/O 完成端口无关的新句柄,然后使用 DuplicateHandle 将其传递给其他进程,它应该可以工作。或者直接调用其他进程中的CreateFile
参考documentation for CreateIoCompletionPort:
A handle can be associated with only one I/O completion port, and after the association is made, the handle remains associated with that I/O completion port until it [the handle] is closed.
[...] The I/O completion port handle and every file handle associated with that particular I/O completion port are known as references to the I/O completion port. The I/O completion port is released when there are no more references to it.
换句话说,关闭 I/O 完成端口句柄没有任何作用。 I/O 完成端口仍然存在并且与管道句柄永久关联。您所尝试的根本不可能;您将需要重新架构。
另请注意:
It is best not to share a file handle associated with an I/O completion port by using either handle inheritance or a call to the DuplicateHandle function. Operations performed with such duplicate handles generate completion notifications. Careful consideration is advised.