在Win32中,光纤是一种用户管理的线程。光纤有自己的堆栈和自己的指令指针等,但操作系统不会调度光纤:您必须显式调用SwitchToFiber。相反,线程由操作系统预先安排。粗略地说,光纤是一个在应用程序/运行时级别管理的线程,而不是真正的OS线程。
结果是光纤更便宜并且应用程序对调度具有更多控制。如果应用程序创建了大量并发任务,并且/或者希望在运行时进行密切优化,这一点非常重要。例如,数据库服务器可能选择使用光纤而不是线程。
(对于同一个术语,可能还有其他用法;如上所述,这是Win32定义。)
首先,我建议阅读这个解释 进程和线程之间的区别 作为背景材料。
一旦你读完它就会很直接。线程可以在内核,用户空间中实现,也可以两者混合使用。光纤基本上是在用户空间中实现的线程。
在现代操作系统的第11.4节“Windows Vista中的进程和线程”中,Tanenbaum评论道:
虽然光纤是合作安排的,但如果有多个 调度光纤的线程,很多细心的同步 要求确保纤维不会相互干扰。至 通常是简化线程和光纤之间的交互 用于创建与要运行的处理器一样多的线程 它们,并将每个运行的线程关联在一组不同的 可用的处理器,甚至只有一个处理器。每个线程都可以 然后运行一个特定的光纤子集,建立一个? 线程和光纤之间的多对多关系简化了 同步。即便如此,仍有许多困难 纤维。大多数Win32库完全没有意识到光纤,而且 尝试使用光纤的应用程序就好像它们是线程一样 遇到各种失败。内核不知道文件, 当光纤进入内核时,它正在执行的线程可以 块和内核将调度一个任意线程 处理器,使其无法运行其他光纤。对于这些 原因很少使用光纤,除非从其他端口移植代码 明确需要光纤提供的功能的系统。
请注意,除了线程和光纤之外,Windows 7还引入了 用户模式调度 :
用户模式调度(UMS)是一种 轻量化的机制 应用程序可以用来安排他们的 自己的线程。应用程序可以切换 在用户模式下的UMS线程之间 不涉及系统调度程序 如果,重新获得对处理器的控制权 内核中的UMS线程阻塞。 UMS 螺纹与纤维不同 每个UMS线程都有自己的线程 上下文而不是共享线程 单个线程的上下文。该 能够在线程之间切换 用户模式使UMS更有效 比用于管理大型的线程池 短期工作项目的数量 这需要很少的系统调用。
有关线程,光纤和UMS的更多信息,请观看 Dave Probert:Windows 7内部 - 用户模式调度程序(UMS) 。
线程使用 的 先发制人 强> 调度,而纤维使用 的 合作社 强> 调度。
使用线程,控制流可以随时中断,另一个线程可以接管。使用多个处理器,您可以同时运行多个线程( 同时 多线程或SMT)。结果,你必须是 非常 注意并发数据访问,并使用互斥锁,信号量,条件变量等保护数据。要想做对,通常都很棘手。
使用光纤时,控制只会在您告诉它时切换,通常使用名为类似的函数调用 yield() 。这使得并发数据访问更容易,因为您不必担心数据结构或互斥锁的原子性。只要你不屈服,就没有存在的危险 抢占 并使用另一根光纤试图读取或修改您正在使用的数据。因此,如果你的光纤进入一个无限循环,没有其他光纤可以运行,因为你没有屈服。
yield()
您还可以混合线和纤维,这会产生两者所面临的问题。不推荐,但如果仔细完成,有时可能是正确的做法。
在最简单的术语中,线程通常被认为是抢先的(尽管这可能并非总是如此,取决于操作系统),而光纤被认为是轻量级的协作线程。两者都是应用程序的独立执行路径。
使用线程:当前执行路径可能随时被中断或抢占(注意:此语句是一般化,并且可能并不总是成立,具体取决于OS /线程包/等)。这意味着对于线程,数据完整性是一个大问题,因为在更新数据块的过程中可能会停止一个线程,从而使数据的完整性处于错误或不完整状态。这也意味着操作系统可以通过同时运行多个线程并将其留给开发人员来保护数据访问,从而利用多个CPU和CPU核心。
对于光纤:当光纤执行时,当前执行路径仅被中断(与上面相同的注释)。这意味着光纤总是在明确定义的位置启动和停止,因此数据完整性不是问题。此外,由于光纤通常在用户空间中进行管理,因此无需进行昂贵的上下文切换和CPU状态更改,从而使从一个光纤更改为下一个光纤非常高效。另一方面,由于没有两根光纤可以完全同时运行,仅使用光纤不会利用多个CPU或多个CPU内核。
线程通常依赖于内核来中断线程,因此它或其他线程可以运行(这更好地称为抢占式多任务处理),而光纤使用协作式多任务处理,其中光纤本身放弃其运行时间,以便其他纤维可以运行。
一些有用的链接解释它比我可能做的更好:
线程最初是作为轻量级进程创建的。以类似的方式,纤维是轻质的线,依靠(简单地)依赖于纤维本身以通过控制来彼此安排。
我想下一步将是你必须在每次你希望他们执行指令时发送信号的链(不像我的5yo儿子:-)。在过去(甚至现在在一些嵌入式平台上),所有线程都是光纤,没有先发制人,你必须编写你的线程以表现得很好。
线程由OS调度(先发制人)。 OS可以随时停止或恢复线程,但是光纤或多或少地管理它们(合作)并相互屈服。也就是说,程序员控制光纤何时进行处理以及何时处理切换到另一根光纤。
Win32光纤定义实际上是在Sun Microsystems建立的“绿色线程”定义。不需要在某种线程上浪费术语光纤,即在用户代码/线程库控制下在用户空间中执行的线程。
要澄清论点,请查看以下注释:
我们应该假设过程是由线程组成的,并且线程应该由纤维制成。考虑到这一逻辑,将纤维用于其他种类的线程是错误的。