.net NET中辅助线程和I/O线程的简单描述

.net NET中辅助线程和I/O线程的简单描述,.net,multithreading,iocp,.net,Multithreading,Iocp,在.NET中很难找到工作线程和I/O线程的详细而简单的描述 关于这个话题,我很清楚(但技术上可能不准确): 工作线程是应该使用CPU进行工作的线程 I/O线程(也称为“完成端口线程”)应使用设备驱动程序进行工作,基本上“什么都不做”,只监视非CPU操作的完成 不清楚的是: 尽管方法ThreadPool.GetAvailableThreads返回两种类型的可用线程数,但似乎没有公共API来调度I/O线程的工作。您只能在.NET中手动创建工作线程吗 似乎单个I/O线程可以监视多个I/O操作。这

在.NET中很难找到工作线程和I/O线程的详细而简单的描述

关于这个话题,我很清楚(但技术上可能不准确):

  • 工作线程是应该使用CPU进行工作的线程
  • I/O线程(也称为“完成端口线程”)应使用设备驱动程序进行工作,基本上“什么都不做”,只监视非CPU操作的完成
不清楚的是:

  • 尽管方法ThreadPool.GetAvailableThreads返回两种类型的可用线程数,但似乎没有公共API来调度I/O线程的工作。您只能在.NET中手动创建工作线程吗
  • 似乎单个I/O线程可以监视多个I/O操作。这是真的吗?如果是这样,为什么默认情况下ThreadPool有这么多可用的I/O线程
  • 在一些文本中,我读到I/O操作完成后触发的回调是由I/O线程执行的。这是真的吗?考虑到这个回调是CPU操作,这不是工作线程的工作吗
  • 更具体地说,ASP.NET异步页面是否包含用户I/O线程?将I/O工作切换到单独的线程,而不是增加工作线程的最大数量,究竟有什么性能优势?是因为单个I/O线程监视多个操作吗?或者Windows在使用I/O线程时进行更有效的上下文切换

简单地说,工作线程意味着执行一段短时间的工作,并将在完成后删除自身。回调可用于通知父进程它已完成或传回数据

I/O线程将连续执行相同的操作或一系列操作,直到被父进程停止。之所以叫它,是因为它通常连续运行设备驱动程序来监视设备端口。I/O线程通常会在希望与其他线程通信时创建事件

所有进程都作为线程运行。 应用程序作为线程运行。 任何线程都可能产生工作线程或I/O线程(如您所称)

在性能和使用的线程数量或类型之间总是有一个很好的平衡。一个进程处理过多的回调或事件将严重降低其性能,因为它在处理这些回调或事件时会中断其主进程循环的次数


工作线程的示例是在用户交互后将数据添加到数据库中,或者执行长时间的数学计算,或者将数据写入文件。通过使用辅助线程释放主应用程序,这对GUI非常有用,因为它在执行任务时不会冻结。

比我技能更高的人将在这里提供帮助

工作线程有很多状态,它们由处理器等调度,您可以控制它们所做的一切


IO完成端口由操作系统为涉及很少共享状态的非常特定的任务提供,因此使用起来更快。Net中的一个很好的例子是WCF框架。对WCF服务的每一次“调用”实际上都是由IO完成端口执行的,因为它们是最快启动的,并且操作系统会为您照看它们。

我将首先介绍NT中的程序如何使用异步I/O

您可能熟悉Win32 API函数ReadFile(例如),它是本机API函数NtReadFile的包装器。此函数允许您使用异步I/O做两件事:

  • 您可以创建事件对象并将其传递给NtReadFile。当读取操作完成时,将发出此事件的信号
  • 您可以将异步过程调用(APC)函数传递给NtReadFile。从本质上讲,这意味着当读取操作完成时,函数将排队到启动操作的线程,并在线程执行可警报的等待时执行
然而,当I/O操作完成时,还有第三种方式可以得到通知。您可以创建I/O完成端口对象并将文件句柄与之关联。每当在与I/O完成端口关联的文件上完成操作时,操作的结果(如I/O状态)将排队到I/O完成端口。然后,您可以设置一个专用线程来从队列中删除结果,并执行适当的任务,如调用回调函数。这就是“I/O工作线程”的本质


正常的“工作线程”非常相似;它不是从队列中删除I/O结果,而是从队列中删除工作项。您可以对工作项(QueueUserWorkItem)进行排队,并让工作线程执行它们。这可以防止您每次异步执行任务时都必须生成线程。

在.net/CLR中,术语“工作线程”通常仅指除主线程以外的代表生成线程的应用程序执行某些“工作”的任何线程“工作”可能真的意味着任何事情,包括等待一些I/O完成。线程池保留工作线程的缓存,因为创建线程的成本很高

.net/CLR中的术语“I/O线程”是指线程池保留的线程,用于从“重叠的”win32调用(也称为“完成端口I/O”)调度本机重叠回调。CLR维护自己的I/O完成端口,并可以将任何句柄绑定到该端口(通过ThreadPool.BindHandle API)。这里的示例:。许多.net API在内部使用此机制来接收本机重叠回调,尽管典型的.net开发人员永远不会直接使用它

“工作线程”和“I/O线程”之间实际上没有技术上的区别——它们都只是普通线程。但是CLR线程池保持