问题标签 [iocp]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
1174 浏览

client - 多线程 IOCP 客户端问题

我正在编写一个使用 IO 完成端口的多线程客户端。

我创建并连接了设置了 WSA_FLAG_OVERLAPPED 属性的套接字。

我将 IO 完成端口与套接字相关联。

在我尝试通过套接字发送一些数据之前,一切似乎都很顺利。

WSASend 不会返回 SOCKET_ERROR 并将最后一个错误设置为 WSA_IO_PENDING,而是立即返回。

我需要 IO 挂起并在我的线程函数中处理它的完成,这也是我的工作线程。

我以前做过,但我不知道在这种情况下出了什么问题,我非常感谢帮助我解决这个问题的任何努力。

0 投票
1 回答
907 浏览

winsock - 一个 IOCP 文档解释问题 - 缓冲区所有权模糊性

由于我不是以英语为母语的人,我可能会遗漏一些东西,所以也许这里有人比我更了解。

取自WSASend在 MSDN 的文档:

lpBuffers [输入]

指向 WSABUF 结构数组的指针。每个 WSABUF 结构都包含一个指向缓冲区的指针和缓冲区的长度(以字节为单位)。对于 Winsock 应用程序,一旦调用 WSASend 函数,系统就拥有这些缓冲区,应用程序可能无法访问它们。该数组必须在发送操作期间保持有效。

好的,你能看到粗体字吗?那是不清楚的地方!

我可以想到这行的两种翻译(可能是别的东西,你可以命名它):
翻译 1 - “缓冲区”指的是我在调用此函数时传递的 OVERLAPPED 结构。只有在收到有关它的完成通知时,我才能再次重用该对象。
翻译 2 - “缓冲区”指的是实际的缓冲区,即那些包含我正在发送的数据的缓冲区。如果 WSABUF 对象指向一个缓冲区,那么在操作完成之前我不能触摸这个缓冲区。

谁能告诉那条线的正确解释是什么?

而且.....如果答案是第二个-您将如何解决?
因为对我来说,这意味着对于我发送的每个数据/缓冲区,我必须在发送方保留一份副本 - 因此在高流量应用程序上有许多“待处理”缓冲区(不同大小),这真的会伤害“可扩展性”。

声明 1:
除了上述段落(“And....”)之外,我认为 IOCP 会将要发送的数据复制到它自己的缓冲区并从那里发送,除非您将SO_SNDBUF设置为零。

声明 2:
我使用堆栈分配的缓冲区(你知道,类似于char cBuff[1024];函数体的内容 - 如果主要问题的转换是第二个选项(即缓冲区必须保持原样,直到发送完成),那么......这真的把事情搞砸了!你能想出办法解决它吗?(我知道,我在上面换句话说)。

0 投票
2 回答
1159 浏览

network-programming - 具有多个缓冲区的 WSASend() - 可以完成不完整吗?

假设我发布了以下 WSASend 调用(没有回调函数的 Windows I/O 完成端口):

当我从完成端口收到“write_done”通知时,是否有可能 wsaBuff[1] 将被完全发送(25 个字节)而 wsaBuff[0] 只会被部分发送(比如 7 个字节)?

0 投票
2 回答
1889 浏览

winsock - ConnectEx 与 IOCP 问题

我使用 IOCP 制作了一个简单的虚拟服务器/虚拟客户端程序,用于某些测试/分析目的。(而且我还想指出,我是异步网络编程的新手)

看起来服务器与原始客户端工作得很好,但是当虚拟客户端尝试使用 ConnectEx 函数连接到服务器时,IOCP Worker 线程仍然被 GetQueuedCompletionStatus 函数阻塞,并且在服务器成功接受连接时从不返回结果。

问题和/或原因是什么,我应该如何解决这个问题?

0 投票
2 回答
2880 浏览

timer - 支持重叠 I/O(用于 IOCP)的计时器?

我需要在基于 I/O 完成端口 (IOCP) 的应用程序中添加计时器支持。我想避免使用特定线程来管理计时器。

在 Linux 上,您可以创建一个通过文件描述符传递到期通知的计时器(请参阅 timerfd.h 手册),因此如果您的应用程序基于 epoll,则可以将其与 epoll 一起使用。

在 Windows 上,您可以将“等待计时器”与异步过程调用 (ACP) 一起使用(请参阅http://msdn.microsoft.com/en-us/library/ms686898(v=VS.85).aspx

如果您有兴趣,kqueue (BSD, Mac OS) 默认支持定时器(参见 EVFILT_TIMER)。

对于 I/O 完成端口,我们必须使用支持重叠 I/O 的对象。那么,有没有这样的 IOCP 计时器?

此致,

塞德里克斯

0 投票
1 回答
402 浏览

windows - 在作业池中使用 iocp

在作业/任务池中使用 iocp 以提供快速的工作人员唤醒时,最大程度地减少向端口发送信号的开销的最佳方法是什么 - 即不必在每个队列操作中都这样做?

void Worker() { while(1) { for(int spin = 0; spin < 5000; ++spin) while(queue.Count > 0) queue.PopFront()();

}

...

queue.PushBack(someWork); // decide when to signal completion port but avoid doing it every queue operation ?

例如,在上面的粗略代码草图中,如果您尝试避免在每次队列操作时向端口发送信号,则在工作排队和进入等待之间存在问题。

0 投票
4 回答
637 浏览

windows - I/O 完成端口可以帮助数据库而不是文件写入吗?

我正在阅读 IOCP,据我所知,异步写入仅适用于写入文件的上下文。我所说的“文件”不仅仅指磁盘文件,而是指 Windows 上的“文件”类型的输出设备。

我计划以某种方式使用 IOCP 来实现一个服务器,该服务器从客户端获取消息,然后将这些消息异步写入数据库(MySQL 或 SQLite)。但是,据我了解,IOCP 中的异步写入涉及将要写入的数据传递给设备驱动程序——而且“设备驱动程序”的提及似乎排除了在数据库上使用 IOCP 和异步写入的可能性,因为有从应用程序编写者的角度来看,不涉及写入数据库的“设备驱动程序”。

那么,IOCP 真的可以帮助实现写入数据库的服务器吗?我有一种唠叨的感觉,我误解了一些东西。

如果 IOCP 在这种情况下无法提供帮助,对于在 Windows 上实现对数据库进行异步写入的服务器,我应该考虑什么建议?

0 投票
1 回答
972 浏览

c++ - 如何正确关闭 IOCP 服务器?

我可以找到大量关于启动 IOCP 服务器的文章,但没有关于正确关闭它的文章 =/

完成后关闭服务器的正确方法是什么?更具体地说,我已经使用PostQueuedCompletionStatus()来告诉工作线程退出,但是我是否还需要取消所有挂起的 IO,并在退出之前关闭所有套接字?

我在 MSDN 上找到了CancelSynchronousIo(),似乎我可以让每个工作线程在收到退出完成通知时调用此函数……这是正确的方法吗?

感谢您对此的任何帮助。

0 投票
2 回答
650 浏览

sockets - Windows IOCP - 单套接字应用程序有什么优势吗?

据我了解 Windows Server 2003/2008 和 C++ 编程下的 IOCP,它们或多或少是服务多个套接字而不是选择或将多个线程捆绑在一起以服务这些请求的最高性能方式。

但是,如果我的程序只有一个套接字,并且考虑到其他限制,通常会读取一个数据包,工作,然后等待另一个数据包,IOCP 会给我带来什么吗?

感觉就像坐在一个 recv() 或等效的一样快,如果在这种特定情况下不是更快的话?

0 投票
4 回答
4456 浏览

windows - 如何找出 CancelIo() 何时完成?

CancelIo()应该取消与调用线程相关的所有挂起的 I/O 操作。根据我的经验,CancelIo() 有时也会取消未来的I/O 操作。鉴于:

  1. CancelIo(port)如果我在读取之前立即调用,GetQueuedCompletionStatus()将永远阻塞,永远不会收到读取操作。
  2. CancelIo(port)如果我在读取后立即调用,GetQueuedCompletionStatus()将返回 0GetLastError()==ERROR_OPERATION_ABORTED
  3. 如果我调用CancelIo(port)并且没有挂起或后续读取,GetQueuedCompletionStatus()将永远阻塞。

这里的关键点是无法检测何时CancelIo()完成执行。如何确保CancelIo()已完成执行并且发出进一步的读取请求是安全的?

PS:查看http://osdir.com/ml/lib.boost.asio.user/2008-02/msg00074.htmlhttp://www.boost.org/doc/libs/1_44_0/doc/html/ boost_asio/using.html听起来 CancelIo() 并不是真的可用。必须客户需要 Windows XP 支持。我有哪些选择?

注意:我正在从串行端口读取。