【问题标题】:Can fibers migrate between threads?纤维可以在线程之间迁移吗?
【发布时间】:2017-12-14 21:08:36
【问题描述】:

在线程 A 中创建的纤程可以切换到在线程 B 中创建的另一个纤程吗?为了使问题更具体,一些操作系统具有原生实现的光纤 (windows fibers),
其他需要自己实现(在 linux 中使用 setjump longjump 等)。

Libcoro 例如将所有这些都包装在一个 API 中(对于 Windows,它只是原生光纤的包装器,对于 Linux,它自己实现它等等)

那么,如果可以在线程之间迁移光纤,你能给我一个 c/c++ 在 windows (linux) 中的用法示例吗?

我在 boost 库 documentation 中发现了一些关于光纤迁移的内容,但是关于它的实现和平台依赖性还不够具体。例如,我仍然想了解如何自己使用 Windows 光纤(或在 linux 上使用 Libcoro)。

如果以一般方式不可能,为什么会这样?

我知道 Fiber 旨在用作 lightweight threads单个线程上进行协作多任务,与常规线程相比,它们具有廉价的上下文切换,并且它们简化了编程。 一个示例用法是具有多个线程的系统,每个线程都有多个纤程在其父线程上执行某种工作层次结构(从不离开父线程)。

即使这不是预期用途,我仍然想学习如何以一般方式实现它,因为我认为我可以通过在线程之间迁移纤程来优化我的作业系统上的工作负载。

【问题讨论】:

  • 至少对于 Windows 光纤来说,答案是“是”。来自the documentation on SwitchToFiber:“您可以调用SwitchToFiber,并使用由不同线程创建的光纤地址。”
  • 我认为不可能有一个通用的答案,因为“纤维”是一个定义松散的术语。从根本上说,纤程从线程捕获执行状态。因此,问题是它是否捕获了完整的状态。

标签: c++ linux windows multithreading fiber


【解决方案1】:

上面提到的 boost.fiber 使用 boost.context (callcc/continuation) 来实现上下文切换。 直到 boost-1.64 callcc 仅在汇编程序中实现,boost-1.65 使您能够在汇编程序、Windows Fibers (Windows) 或 ucontext(POSIX 如果可用;POSIX 弃用的 API)之间进行选择。 汇编器实现比其他两个更快(与 ucontext 相比 2 个数量级)。

boost.fiber 使用 callcc 来实现轻量级线程/纤程 - 该库提供纤程调度程序,允许在线程之间迁移纤程。 例如,一个提供的调度程序在其运行队列停止工作时从其他线程窃取纤程(纤程就绪/可以恢复)。

(因此您可以选择在线程之间迁移的 Windows 光纤)。

【讨论】:

  • 您的回答非常有帮助且内容丰富,但并没有直接回答我的问题。您能否添加一个示例,说明如何使用 boost.context (callcc/continuation) 以安全的方式在线程之间迁移(清理在另一个线程中创建的上下文时不会损坏堆栈)?
猜你喜欢
  • 2021-06-08
  • 2021-10-09
  • 2017-06-30
  • 2011-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-14
相关资源
最近更新 更多