【问题标题】:Windows overlapped IO vs IO on separate threadWindows 在单独的线程上重叠 IO 与 IO
【发布时间】:2014-09-04 01:52:30
【问题描述】:

在 Windows 上,当您执行 I/O 时,您可以使用 OVERLAPPED 选项异步执行。这样做与在另一个线程上同步执行 I/O 有什么区别吗?如果是这样,哪个更好?操作系统是否只是在异步情况下生成一个单独的线程,或者它只是在驱动程序线程上排队并发送信号而不是阻塞等待?

谢谢!

【问题讨论】:

  • 操作系统几乎肯定不会仅仅为了服务重叠的 I/O 请求而产生新线程。查找I/O completion ports,它实际上需要您提供自己的线程来从 I/O 完成端口中提取完成通知。确切地说,Windows 是如何做到这一点的只是一个实现细节,但由于它是一个操作系统,它除了产生线程之外还可以发挥一些技巧。
  • 异步 i/o 的结果好坏参半——尤其是 WriteFile 调用。使用 OVERLAPPED 标志调用的某些 WriteFile 操作实际上会阻塞而不是立即返回。尽管我想让重叠的 i/o 工作正常工作,但它只是增加了代码的复杂性,因为我仍然必须轮询/等待重叠操作完成......最后,“产生一个线程”方法实际上更易于实施,并且不会造成任何不良影响。 YMMV。制作原型并进行测量以确认预期收益 - 结果可能会让您大吃一惊。

标签: windows asynchronous overlapped-io


【解决方案1】:

Windows I/O 本质上是异步的,因此在 .NET 中执行异步操作,例如 should not use a thread,一旦操作完成,一些现有线程会短暂借用以通知操作完成,但不会创建线程。

这与在另一个线程上运行同步操作完全不同。它占用了一个线程,使程序的可伸缩性大大降低。在 .NET 中,线程的默认本地存储为 1MB,因此运行数千个线程将消耗千兆字节的内存。然后,您还会有在线程之间切换的额外成本,这通常很小,但如果您有很多线程,则可以加起来。

【讨论】:

  • 请注意,默认情况下,FileStream 上的 .NET 异步方法使用线程。您可以在其构造函数中指定isAsync: true 以获得使用重叠IO 的FileStream,但似乎在最常见的使用场景中,这比默认线程IO 执行得更差。因此,默认情况下,在 .NET 上,用户空间中有一个线程。现在,由于它使用ThreadPool,因此创建线程的成本是分摊的,并且堆栈大小不会成为问题,因为工作队列和自动池大小调整通常可以避免数千个线程。
【解决方案2】:

根据 MSDN 开发中心,“异步 I/O 也称为重叠 I/O”此外,它继续说异步 io 由内核处理,实际上是另一个线程。我不了解你,但如果我不必写东西,我不会……这是我懒惰的程序员规则#1。

【讨论】:

  • 好吧,考虑到我有一个用于其他目的的线程池,并且同步 IO 比 OVERLAPPED IO 更容易编写代码,我可以把它扔到我的池中的一个线程上。但是想知道使用 OVERLAPPED 与只是扔到另一个线程上是否有任何好处......
  • 这个问题回答了stackoverflow.com/questions/3050621/… 说速度差别不大,但是一个人确实在线程池中使用异步状态,您的应用程序可以处理任意数量的 IO 调用,例如在服务器中。
猜你喜欢
  • 1970-01-01
  • 2017-10-12
  • 2017-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-12
  • 2014-01-02
  • 1970-01-01
相关资源
最近更新 更多