.net NET中辅助线程和I/O线程的简单描述
在.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操作。这
- 工作线程是应该使用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线程时进行更有效的上下文切换
工作线程的示例是在用户交互后将数据添加到数据库中,或者执行长时间的数学计算,或者将数据写入文件。通过使用辅助线程释放主应用程序,这对GUI非常有用,因为它在执行任务时不会冻结。比我技能更高的人将在这里提供帮助 工作线程有很多状态,它们由处理器等调度,您可以控制它们所做的一切
IO完成端口由操作系统为涉及很少共享状态的非常特定的任务提供,因此使用起来更快。Net中的一个很好的例子是WCF框架。对WCF服务的每一次“调用”实际上都是由IO完成端口执行的,因为它们是最快启动的,并且操作系统会为您照看它们。我将首先介绍NT中的程序如何使用异步I/O 您可能熟悉Win32 API函数ReadFile(例如),它是本机API函数NtReadFile的包装器。此函数允许您使用异步I/O做两件事:
- 您可以创建事件对象并将其传递给NtReadFile。当读取操作完成时,将发出此事件的信号
- 您可以将异步过程调用(APC)函数传递给NtReadFile。从本质上讲,这意味着当读取操作完成时,函数将排队到启动操作的线程,并在线程执行可警报的等待时执行
正常的“工作线程”非常相似;它不是从队列中删除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线程池保持