线和纤维有什么区别?

发布于 2024-07-18 00:57:50 字数 70 浏览 5 评论 0原文

线和纤维有什么区别? 我听说过红宝石纤维,也听说过它们有其他语言版本,有人可以用简单的术语向我解释一下线和纤维之间的区别吗?

What is the difference between a thread and a fiber? I've heard of fibers from ruby and I've read heard they're available in other languages, could somebody explain to me in simple terms what is the difference between a thread and a fiber.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

空袭的梦i 2024-07-25 00:57:50

用最简单的术语来说,线程通常被认为是抢占式的(尽管这可能并不总是正确的,具体取决于操作系统),而光纤则被认为是轻量级的协作线程。 两者都是应用程序的单独执行路径。

对于线程:当前执行路径可能随时被中断或抢占(注意:此声明是概括性的,并且可能并不总是成立,具体取决于操作系统/线程包/等)。 这意味着对于线程来说,数据完整性是一个大问题,因为一个线程可能会在更新一大块数据的过程中停止,从而使数据的完整性处于不良或不完整的状态。 这也意味着操作系统可以通过同时运行多个线程来利用多个 CPU 和 CPU 内核,并由开发人员来保护数据访问。

对于纤程:只有当纤程产生执行时,当前执行路径才会被中断(与上面的注释相同)。 这意味着光纤始终在明确定义的位置启动和停止,因此数据完整性不再是问题。 此外,由于纤程通常在用户空间中进行管理,因此无需进行昂贵的上下文切换和 CPU 状态更改,从而使得从一个纤程到下一个纤程的更改极其高效。 另一方面,由于没有两个纤程可以完全相同地运行,因此仅使用纤程将无法充分利用多个 CPU 或多 CPU 核心。

In the most simple terms, threads are generally considered to be preemptive (although this may not always be true, depending on the operating system) while fibers are considered to be light-weight, cooperative threads. Both are separate execution paths for your application.

With threads: the current execution path may be interrupted or preempted at any time (note: this statement is a generalization and may not always hold true depending on OS/threading package/etc.). This means that for threads, data integrity is a big issue because one thread may be stopped in the middle of updating a chunk of data, leaving the integrity of the data in a bad or incomplete state. This also means that the operating system can take advantage of multiple CPUs and CPU cores by running more than one thread at the same time and leaving it up to the developer to guard data access.

With fibers: the current execution path is only interrupted when the fiber yields execution (same note as above). This means that fibers always start and stop in well-defined places, so data integrity is much less of an issue. Also, because fibers are often managed in the user space, expensive context switches and CPU state changes need not be made, making changing from one fiber to the next extremely efficient. On the other hand, since no two fibers can run at exactly the same time, just using fibers alone will not take advantage of multiple CPUs or multiple CPU cores.

笑脸一如从前 2024-07-25 00:57:50

线程使用抢占式调度,而纤程使用协作调度。

对于线程,控制流可能随时中断,另一个线程可以接管。 使用多个处理器,您可以同时运行多个线程(同步多线程,或 SMT)。 因此,您必须非常小心并发数据访问,并使用互斥体、信号量、条件变量等保护您的数据。 要做到正确往往非常棘手。

对于光纤,控制仅在您告诉它时才切换,通常使用名为 yield() 的函数调用。 这使得并发数据访问变得更容易,因为您不必担心数据结构或互斥体的原子性。 只要您不让步,就不会有被抢占的危险,也不会有其他光纤尝试读取或修改您正在使用的数据的危险。 但结果是,如果您的光纤进入无限循环,则其他光纤都无法运行,因为您没有屈服。

您还可以混合线和纤维,这会引起两者面临的问题。 不建议这样做,但如果谨慎行事,有时可能是正确的做法。

Threads use pre-emptive scheduling, whereas fibers use cooperative scheduling.

With a thread, the control flow could get interrupted at any time, and another thread can take over. With multiple processors, you can have multiple threads all running at the same time (simultaneous multithreading, or SMT). As a result, you have to be very careful about concurrent data access, and protect your data with mutexes, semaphores, condition variables, and so on. It is often very tricky to get right.

With a fiber, control only switches when you tell it to, typically with a function call named something like yield(). This makes concurrent data access easier, since you don't have to worry about atomicity of data structures or mutexes. As long as you don't yield, there's no danger of being preempted and having another fiber trying to read or modify the data you're working with. As a result, though, if your fiber gets into an infinite loop, no other fiber can run, since you're not yielding.

You can also mix threads and fibers, which gives rise to the problems faced by both. Not recommended, but it can sometimes be the right thing to do if done carefully.

拿命拼未来 2024-07-25 00:57:50

首先,我建议阅读进程和线程之间的区别的解释作为背景材料。

一旦你读完,它就非常简单了。 线程可以在内核、用户空间中实现,或者两者可以混合实现。 纤维基本上是在用户空间中实现的线程。

  • 通常所说的线程是在内核中实现的执行线程:即所谓的内核线程。 内核线程的调度完全由内核处理,尽管内核线程可以根据需要通过休眠来自愿释放 CPU。 内核线程的优点是可以使用阻塞 I/O,而让内核操心调度。 它的主要缺点是线程切换相对较慢,因为它需要陷入内核。
  • 纤程是用户空间线程,其调度由单个进程下的一个或多个内核线程在用户空间中处理。 这使得光纤切换非常快。 如果将访问一组特定共享数据的所有纤程分组在单个内核线程的上下文中,并由单个内核线程处理它们的调度,那么您可以消除同步问题,因为纤程将有效地串行运行,并且您已经完成了控制他们的日程安排。 将相关纤程分组到单个内核线程下非常重要,因为它们运行的​​内核线程可以被内核抢占。 这一点在其他很多答案中都没有说清楚。 另外,如果您在纤程中使用阻塞 I/O,则整个内核线程都是块的一部分,包括属于该内核线​​程的所有纤程。

在《现代操作系统》第 11.4 节“Windows Vista 中的进程和线程”中,Tanenbaum 评论道:

虽然纤程是协同调度的,但是如果有多个纤程
线程调度纤程,需要非常仔细的同步
需要确保纤维不会相互干扰。 到
简化线和纤维之间的相互作用,通常
仅创建与要运行的处理器一样多的线程很有用
它们,并将线程关联到每个线程仅在一组不同的
可用的处理器,甚至只有一个处理器。 每个线程都可以
然后运行纤维的特定子集,建立一个
线程和纤维之间的多对多关系简化了
同步。 即便如此,仍面临诸多困难
纤维。 大多数 Win32 库完全不知道纤程,并且
尝试像使用线程一样使用纤维的应用程序将
遇到各种失败。 内核对纤维一无所知,
当纤程进入内核时,它正在执行的线程可能
块并且内核将在该块上调度任意线程
处理器,使其无法运行其他光纤。 对于这些
除非从其他地方移植代码,否则很少使用光纤的原因
明确需要光纤提供的功能的系统。

First I would recommend reading this explanation of the difference between processes and threads as background material.

Once you've read that it's pretty straight forward. Threads cans be implemented either in the kernel, in user space, or the two can be mixed. Fibers are basically threads implemented in user space.

  • What is typically called a thread is a thread of execution implemented in the kernel: what's known as a kernel thread. The scheduling of a kernel thread is handled exclusively by the kernel, although a kernel thread can voluntarily release the CPU by sleeping if it wants. A kernel thread has the advantage that it can use blocking I/O and let the kernel worry about scheduling. It's main disadvantage is that thread switching is relatively slow since it requires trapping into the kernel.
  • Fibers are user space threads whose scheduling is handled in user space by one or more kernel threads under a single process. This makes fiber switching very fast. If you group all the fibers accessing a particular set of shared data under the context of a single kernel thread and have their scheduling handled by a single kernel thread, then you can eliminate synchronization issues since the fibers will effectively run in serial and you have complete control over their scheduling. Grouping related fibers under a single kernel thread is important, since the kernel thread they are running in can be pre-empted by the kernel. This point is not made clear in many of the other answers. Also, if you use blocking I/O in a fiber, the entire kernel thread it is a part of blocks including all the fibers that are part of that kernel thread.

In section 11.4 "Processes and Threads in Windows Vista" in Modern Operating Systems, Tanenbaum comments:

Although fibers are cooperatively scheduled, if there are multiple
threads scheduling the fibers, a lot of careful synchronization is
required to make sure fi­bers do not interfere with each other. To
simplify the interaction between threads and fibers, it is often
useful to create only as many threads as there are processors to run
them, and affinitize the threads to each run only on a distinct set of
avail­able processors, or even just one processor. Each thread can
then run a particular subset of the fibers, establishing a one­
to-many relationship between threads and fibers which simplifies
synchronization. Even so there are still many difficulties with
fibers. Most Win32 libraries are completely unaware of fibers, and
applications that attempt to use fibers as if they were threads will
encounter various failures. The kernel has no knowledge of fi­bers,
and when a fiber enters the kernel, the thread it is executing on may
block and the kernel will schedule an arbitrary thread on the
processor, making it unavailable to run other fibers. For these
reasons fibers are rarely used except when porting code from other
systems that explicitly need the functionality pro­vided by fibers.

我的奇迹 2024-07-25 00:57:50

在 Win32 中,纤程是一种用户管理的线程。 纤程有自己的堆栈和指令指针等,但纤程不由操作系统调度:您必须显式调用 SwitchToFiber。 相比之下,线程是由操作系统抢先调度的。 因此粗略地说,纤程是在应用程序/运行时级别管理的线程,而不是真正的操作系统线程。

其结果是光纤更便宜,并且应用程序对调度有更多的控制权。 如果应用程序创建大量并发任务,和/或希望在运行时进行密切优化,这一点可能很重要。 例如,数据库服务器可能选择使用纤程而不是线程。

(同一术语可能有其他用法;如前所述,这是 Win32 定义。)

In Win32, a fiber is a sort of user-managed thread. A fiber has its own stack and its own instruction pointer etc., but fibers are not scheduled by the OS: you have to call SwitchToFiber explicitly. Threads, by contrast, are pre-emptively scheduled by the operation system. So roughly speaking a fiber is a thread that is managed at the application/runtime level rather than being a true OS thread.

The consequences are that fibers are cheaper and that the application has more control over scheduling. This can be important if the app creates a lot of concurrent tasks, and/or wants to closely optimise when they run. For example, a database server might choose to use fibers rather than threads.

(There may be other usages for the same term; as noted, this is the Win32 definition.)

若相惜即相离 2024-07-25 00:57:50

请注意,除了线程和纤程之外,Windows 7 还引入了用户模式调度

用户模式调度(UMS)是
轻量级机制
应用程序可以用来安排他们的
自己的线程。 应用程序可以切换
用户模式下的 UMS 线程之间
不涉及系统调度程序
并重新获得处理器的控制权,如果
UMS 线程在内核中阻塞。 UMS
线与纤维的不同之处在于
每个UMS线程都有自己的线程
上下文而不是共享线程
单个线程的上下文。 这
能够在线程之间切换
用户模式让UMS更高效
比管理大的线程池
短期工作项目数量
需要很少的系统调用。

有关线程、光纤和 UMS 的更多信息,请观看 Dave Probert:Windows 7 内部 - 用户模式调度程序 (UMS)

Note that in addition to Threads and Fibers, Windows 7 introduces User-Mode Scheduling:

User-mode scheduling (UMS) is a
light-weight mechanism that
applications can use to schedule their
own threads. An application can switch
between UMS threads in user mode
without involving the system scheduler
and regain control of the processor if
a UMS thread blocks in the kernel. UMS
threads differ from fibers in that
each UMS thread has its own thread
context instead of sharing the thread
context of a single thread. The
ability to switch between threads in
user mode makes UMS more efficient
than thread pools for managing large
numbers of short-duration work items
that require few system calls.

More information about threads, fibers and UMS is available by watching Dave Probert: Inside Windows 7 - User Mode Scheduler (UMS).

无妨# 2024-07-25 00:57:50

线程通常依靠内核来中断线程,以便它或另一个线程可以运行(这更好地称为抢占式多任务处理),而纤程使用协作多任务处理,其中纤程本身放弃其运行时间,以便其他光纤可以运行。

一些比我更好地解释它的有用链接是:

Threads generally rely on the kernel to interrupt the thread so it or another thread can run (which is better known as Pre-emptive multitasking) whereas fibers use co-operative multitasking where it is the fiber itself that give up the its running time so that other fibres can run.

Some useful links explaining it better than I probably did are:

随风而去 2024-07-25 00:57:50

线程最初是作为轻量级进程创建的。 以类似的方式,纤程是一种轻量级线程,(简单地)依靠纤程本身通过让出控制来相互调度。

我想下一步将是每次你希望他们执行指令时你都必须向他们发送一个信号(与我 5 岁的儿子不同:-)。 在过去(甚至现在在某些嵌入式平台上),所有线程都是纤程,没有抢占,您必须编写线程才能表现良好。

Threads were originally created as lightweight processes. In a similar fashion, fibers are a lightweight thread, relying (simplistically) on the fibers themselves to schedule each other, by yielding control.

I guess the next step will be strands where you have to send them a signal every time you want them to execute an instruction (not unlike my 5yo son :-). In the old days (and even now on some embedded platforms), all threads were fibers, there was no pre-emption and you had to write your threads to behave nicely.

如果没结果 2024-07-25 00:57:50

线程由操作系统调度(抢占式)。 操作系统可以随时停止或恢复线程,但纤程或多或少会自我管理(协作)并相互让步。 也就是说,程序员控制光纤何时进行处理以及该处理何时切换到另一根光纤。

Threads are scheduled by the OS (pre-emptive). A thread may be stopped or resumed at any time by the OS, but fibers more or less manage themselves (co-operative) and yield to each other. That is, the programmer controls when fibers do their processing and when that processing switches to another fiber.

心如狂蝶 2024-07-25 00:57:50

Win32 光纤定义实际上是 Sun Microsystems 建立的“Green Thread”定义。 没有必要在某种线程上浪费术语“纤程”,即在用户代码/线程库控制下在用户空间中执行的线程。

为了澄清这一论点,请看以下评论​​:

  • 通过超线程,多核 CPU 可以接受多个线程并将它们分配到每个核心上。
  • 超标量流水线 CPU 接受一个线程执行,并使用指令级并行 (ILP) 来更快地运行线程。 我们可以假设一个线程被分成在并行管道中运行的并行纤维。
  • SMT CPU 可以接受多个线程,并将它们分解为指令纤维,以便在多个管道上并行执行,从而更有效地使用管道。

我们应该假设进程是由线程组成的,而线程应该是由纤维组成的。 考虑到这一逻辑,将纤维用于其他类型的线程是错误的。

Win32 fiber definition is in fact "Green Thread" definition established at Sun Microsystems. There is no need to waste the term fiber on the thread of some kind, i.e., a thread executing in user space under user code/thread-library control.

To clarify the argument look at the following comments:

  • With hyper-threading, a multi-core CPU can accept multiple threads and distribute them one on each core.
  • Superscalar pipelined CPU accepts one thread for execution and uses Instruction Level Parallelism (ILP) to run the thread faster. We may assume that one thread is broken into parallel fibers running in parallel pipelines.
  • SMT CPU can accept multiple threads and break them into instruction fibers for parallel execution on multiple pipelines, using pipelines more efficiently.

We should assume that processes are made of threads and that threads should be made of fibers. With that logic in mind, using fibers for other sorts of threads is wrong.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文