我目前正在研究一种基于使用 IO 完成端口的命名管道的 IPC 机制。
不幸的是,我在使用 msdn 文档时遇到了一些麻烦,因为我不清楚在哪种情况下调用 ReadFile/WriteFile 会产生完成数据包。
当 ERROR_IO_PENDING 返回 FALSE 时的情况很清楚,但是当返回 ERROR_MORE_DATA 时明显可能的情况又如何呢?这种情况下会有完成包吗?另外,如果返回其他错误怎么办?在哪些情况下我必须直接处理结果并释放资源,而不是在完成处理程序中?
另一种情况是 ReadFile/WriteFile 甚至成功,这显然也是可能的。值得庆幸的是,MSDN对此非常清楚:
此外,WriteFile 函数有时会返回 TRUE,且 GetLastError 值为 ERROR_SUCCESS,即使它使用的是异步句柄(也可能因 ERROR_IO_PENDING 而返回 FALSE)。...在此示例中,建议允许完成端口例程单独负责此类资源的所有释放操作。
这个建议在所有情况下都是正确的吗?分配给完成端口的句柄的 ReadFile/WriteFile 操作的结果实际上可以(并且应该)完全被忽略,因为数据包无论如何都会发送到端口?
windows winapi named-pipes overlapped-io io-completion-ports
我需要在基于I/O完成端口(IOCP)的应用程序中添加定时器支持.我想避免使用特定的线程来管理计时器.
在Linux上,您可以创建一个通过文件描述符提供过期通知的计时器(请参阅timerfd.h man),因此如果您的应用程序基于epoll,那么将它用于epoll非常棒.
在Windows上,您可以使用"waitable timers"和异步过程调用(ACP)(请参阅http://msdn.microsoft.com/en-us/library/ms686898(v=VS.85).aspx)
如果您有兴趣,kqueue(BSD,Mac OS)默认支持计时器(请参阅EVFILT_TIMER).
使用I/O完成端口,我们必须使用支持重叠I/O的objets.那么,IOCP有这样的计时器吗?
最好的祝福,
Cédrics
我们正在将现有的 Windows 代码移植到 Linux。我们使用 ACE 作为抽象层。我们使用 Windows 命名管道与多个客户端进行通信并执行重叠操作。
在 linux 中与此等效的是什么。我检查了 linux 命名管道(FIFO),但它们似乎只支持一个客户端和一个服务器,并且不支持重叠 IO。
你能指导我吗?
我正在使用重叠 IO,我想使用阻塞调用接受客户端连接,就像我使用普通accept(). 我不确定,但我认为这AcceptEx()不会阻止,而WSAAccept()会阻止。那么WSAAccept()类似于accept()?
我有一个正在包装的 C dll,以便可以从 C# 调用它。当状态发生变化时,一个函数使用事件来通知您,并且需要进行一些挖掘才能找到处理它的方法。它似乎工作正常,但我很好奇是否有人比我有更多的经验并且可以提供任何建议。
该函数在 dll 的 .h 文件中定义为:
int NotifyStateChange(OVERLAPPED *overlapped);
typedef int (*NOTIFY_STATE_CHANGE_PROC)(OVERLAPPED *);
Run Code Online (Sandbox Code Playgroud)
调用它的示例 C 代码:
OVERLAPPED overlapped;
overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
fns.NotifyStateChange(&overlapped);
WaitForSingleObject(overlapped.hEvent, INFINITE);
// ...query for the new state or whatever...
Run Code Online (Sandbox Code Playgroud)
这就是我在 C# 中的处理方式:
[DllImport("myfuncs.dll")]
unsafe public static extern int NotifyStateChange(NativeOverlapped* lpOverlapped);
static private ManualResetEvent m_stateChangeEvent = new ManualResetEvent(false);
public static DeviceState WaitForStateChange()
{
unsafe
{
Overlapped overlapped = new Overlapped(0, 0,
m_stateChangeEvent.SafeWaitHandle.DangerousGetHandle(), null);
IOCompletionCallback callback = StateChangeCallback;
byte[] userData = new …Run Code Online (Sandbox Code Playgroud) 是否可以使用重叠的I/O启动TCP连接请求,并在Windows中完成连接之前取消它?我需要至少支持Windows XP SP2.
在Windows应用程序中,我有一个包装文件名和缓冲区的类.您使用文件名构造它,您可以查询对象以查看缓冲区是否已填充,如果没有则返回nullptr,如果是,则返回缓冲区地址.当对象超出范围时,释放缓冲区:
class file_buffer
{
public:
file_buffer(const std::string& file_name);
~file_buffer();
void* buffer();
private:
...
}
Run Code Online (Sandbox Code Playgroud)
我想异步将数据放入内存,据我所知,我有两个选择:创建一个缓冲区并通过ReadFileEx使用重叠IO,或者使用MapViewOfFile并触摸另一个线程上的地址.
目前我正在使用ReadFileEx,这会出现一些问题,因为大于16MB的请求容易出现故障:我可以尝试拆分请求,但后来我遇到同步问题,如果在IO之前对象超出范围完成我有缓冲区清理问题.此外,如果快速连续创建类的多个实例,则会非常繁琐.
映射和触摸另一个线程上的数据似乎相当容易,因为我没有上限问题:如果客户端现在绝对必须拥有数据,他们可以简单地取消引用地址,让操作系统担心页面错误并采取阻止命中.
这个应用程序需要支持单核机器,所以我的问题是:另一个软件线程的页面错误是否会比当前线程上的重叠IO更昂贵?他们会拖延这个过程吗?重叠的IO是否以相同的方式停止进程,或者是否存在一些我不明白的操作系统魔法?是否使用重叠IO执行页面错误?
我已经很好地阅读了这些主题:http: //msdn.microsoft.com/en-us/library/aa365199(v = vs.85).aspx(文件管理中的IO概念) http:// msdn. microsoft.com/en-us/library/windows/desktop/aa366556 (v=vs.85) .aspx(文件映射),但我似乎无法推断如何进行性能权衡.
我需要同时(即异步)从文件中读取几行。文件中的行大小相同。
例如,我需要读取文件的第二行和第四行以分隔变量或数组。
我更习惯于c#的异步/等待,所有这些OVERLAPPED事情对我来说都有点难以理解。
使用msdn示例,我实现了这一点,它只是将文件中的数据作为一个字符串读取(甚至是异步读取吗?):
BOOL ReadFromFileAsync(PCTSTR path)
{
HANDLE hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
_tprintf_s(TEXT("INVALID_HANDLE_VALUE\n"));
return FALSE;
}
BOOL bResult;
BYTE bReadBuf[2048];
OVERLAPPED oRead = { 0 };
oRead.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
bResult = ReadFile(hFile, bReadBuf, _countof(bReadBuf), NULL, &oRead);
if (!bResult && GetLastError() != ERROR_IO_PENDING)
{
_tprintf_s(TEXT("ERROR io pending"));
CloseHandle(hFile);
return FALSE;
}
// perform some stuff asynchronously
_tprintf_s(TEXT("HEY\n"));
HANDLE hEvents[2];
hEvents[0] = oRead.hEvent;
hEvents[1] …Run Code Online (Sandbox Code Playgroud) 假设您正在ReadDirectoryChangesW使用 I/O 完成端口执行异步操作(如)。对于每次调用该函数,您分配一个OVERLAPPED结构(可能带有一些附加数据)以在 I/O 完成回调中使用。然后在回调中,在使用OVERLAPPED结构后,您使用作为参数提供的指针释放内存。
现在让我们说是时候关闭一切并取消任何挂起的异步调用了。是否有可以调用的函数来检索指向OVERLAPPED任何当前挂起的 I/O 操作中使用的结构的指针,以便您可以释放内存?
出于某种原因,我的回调OVERLAPPED在调用ReadFileEx. 什么会导致这种情况?
更新 - 示例:
#include <stdio.h>
#include <Windows.h>
void __stdcall completion_routine(
unsigned long dwErrorCode,
unsigned long dwNumberOfBytesTransfered,
OVERLAPPED *lpOverlapped)
{
printf("Overlapped = %p\n", lpOverlapped);
}
int _tmain(int argc, LPTSTR argv[])
{
HANDLE hvolume = CreateFile(
_T("C:\\Windows\\Notepad.exe"), FILE_READ_DATA,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, 0, NULL);
char tempbuf[512];
OVERLAPPED tempoverlapped = { };
printf("%p\n", &tempoverlapped);
if (ReadFileEx(hvolume, tempbuf, sizeof(tempbuf),
&tempoverlapped, &completion_routine)
&& GetLastError() == ERROR_SUCCESS)
{
SleepEx(INFINITE, TRUE);
}
}
Run Code Online (Sandbox Code Playgroud) 有没有人设法弄清楚NtQueryDirectoryFile的异步调用是如何工作的?
通过异步调用,我的意思是调用未使用FILE_SYNCHRONOUS_IO_ALERT或FILE_SYNCHRONOUS_IO_NONALERT打开的NtQueryDirectoryFile目录.
对我来说,它似乎STATUS_PENDING像普通的NtReadFile请求一样返回普通文件,但是当我尝试在目录上使用NtWaitForSingleObject时,它没有正确结束,我仍然没有获得所有数据...为什么这会发生吗?
overlapped-io ×11
winapi ×8
c++ ×3
file-io ×2
named-pipes ×2
asynchronous ×1
c ×1
c# ×1
createfile ×1
directory ×1
file-mapping ×1
filehandle ×1
iocp ×1
linux ×1
pinvoke ×1
sockets ×1
tcp ×1
timer ×1
visual-c++ ×1
windows ×1
winsock ×1