从线程2中启动线程1中的增强光纤

发布于 2025-02-10 11:15:39 字数 734 浏览 3 评论 0 原文

我有一个主要的Linux线程(TH1),该线程运行了使用Boost Priority Scheduler计划进行的许多增强纤维。

每隔一段时间,我都想从另一个线程(TH2)发射一根光纤,该线程将在Th1中运行,并与其他TH1纤维一起安排。我用来在Th1中启动纤维的代码看起来像:

void launchFiber()
{
boost::fibers::use_scheduling_algorithm< priority_scheduler >()
boost::fibers::fiber *fib = new boost::fibers::fiber(fb_fiberFunction);
priority_props & props( fib->properties< priority_props >() );
props.set_priority(FiberPriorityValue);
props.name = "Fiber Name";
fib->detach();
}

启动代码从TH1调用启动纤维函数时可以正常工作,但是当我从TH2调用它时它不起作用 - 看起来纤维没有添加到TH1光纤中队列。我已经在th1 Priority_scheduler例程中添加了一个静音,以保护纤维队列,但这似乎没有帮助。

在我看来,当涉及多个线程时,我真的不明白光纤系统的工作原理。我试图查看库源代码,但对我来说并不清楚。

我的猜测是,如果我正确理解它,这将很简单。有人可以提供我如何做到这一点的例子。

I have a main linux thread (th1) that runs a number of boost fibers that are scheduled using the boost priority scheduler.

Every so often, I would like to launch a fiber from another thread (th2) that will run in th1 and be scheduled along with the other th1 fibers. The code I use to launch fibers in th1 looks like:

void launchFiber()
{
boost::fibers::use_scheduling_algorithm< priority_scheduler >()
boost::fibers::fiber *fib = new boost::fibers::fiber(fb_fiberFunction);
priority_props & props( fib->properties< priority_props >() );
props.set_priority(FiberPriorityValue);
props.name = "Fiber Name";
fib->detach();
}

The launch code works fine when I call the launchFiber function from th1 but it does not work when I call it from th2--it looks like the fiber is not added to the th1 fiber queue. I have added a mutex to the th1 priority_scheduler routine to protect the fiber queue but this doesn't seem to help.

It seems to me that I don't really understand how the fiber system is working when there is more than one thread involved. I have tried to look at the library source code but it is not really clear to me.

My guess is that this would be simple if I understood it correctly. Could someone provide an example of how I might do this.

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

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

发布评论

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

评论(2

ヤ经典坏疍 2025-02-17 11:15:40

与系统线程相反,纤维基于合作计划。这意味着您应该在可以安排其他光纤的时候手动告诉调度程序。调度程序可以选择在此用户定义的调度点期间进行计划的最佳光纤。在这里,调度程序将选择优先级最高的一个。如果没有优先级较高的纤维,则相同的光纤可以简历其执行。

每个纤维都有自己的堆栈。
光纤可以保存当前的执行状态,包括所有寄存器和CPU标志,指令指针以及堆栈指针,然后还原该状态。这个想法是要使用合作计划在单个线程上运行多个执行路径(与线程相比,预先计划)。运行的光纤明确决定何时应屈服,以允许另一个光纤运行(上下文切换)。
控制是合作在给定线程上启动的纤维之间传递的。在给定的时刻,在给定的线程上,最多一根光纤正在运行。在给定线程上产生其他纤维不会在更多的硬件内核上分发您的程序,尽管它可以更有效地利用其运行的核心。

旨在在当前光纤上执行实际收益率操作。

请注意,如果纤维在线程之间移动(默认情况下不是默认情况下),并且使用Basic Basic Mutex/条件变量也不安全,则与螺纹本地存储保持不安全出现在受保护的代码(关键部分)的中间,因为它可能导致死锁。它也可以是最佳选择,因为静音会导致当前线被预先避开或被动地等待,而另一只光纤可以进行计算。 Boost为纤维提供了更安全/更有效的纤维的替代同步机制,尽管仍然需要关心这一点。这就是为什么纤维不能盲目执行任何任意代码的原因。

有关更多信息,您可以查看示例 a href =“ https://github.com/boostorg/fiber/blob/develop/examples/simple.cpp” rel =“ nofollow noreferrer”>最简单的一个。

Contrary to system threads, fibers are based on cooperative scheduling. This means that you should manually tell to the scheduler when another fiber can be scheduled. The scheduler can choose the best fiber to schedule during this user-defined scheduling point. Here, the scheduler will choose the one with the highest priority. If there are no fibers with higher priority, then the same fiber can resume its execution back. The documentation states:

Each fiber has its own stack.
A fiber can save the current execution state, including all registers and CPU flags, the instruction pointer, and the stack pointer and later restore this state. The idea is to have multiple execution paths running on a single thread using cooperative scheduling (versus threads, which are preemptively scheduled). The running fiber decides explicitly when it should yield to allow another fiber to run (context switching).
Control is cooperatively passed between fibers launched on a given thread. At a given moment, on a given thread, at most one fiber is running. Spawning additional fibers on a given thread does not distribute your program across more hardware cores, though it can make more effective use of the core on which it's running.

this_fiber::yield() is meant to perform the actual yields operations on the current fiber.

Note that fibers are not safely compatible with thread-local storage if they are moved between threads (not the case by default) and using basic basic mutex/condition variables is not safe either, particularly if a yield can appear in a middle of a protected code (critical section) as it can cause deadlocks. It can also be sub-optimal because mutexes can cause the current thread to be pre-empted or passively waiting while another fiber could do computations. Boost provide alternative synchronisation mechanisms for fibers that are safer/more-efficient though one still need to care about that. This is why fibers cannot be used to execute any arbitrary code blindly.

For more information, you can give a look to the examples starting from the simplest one.

亢潮 2025-02-17 11:15:40

我确实花了一些时间研究这个问题。事实证明,执行命令: boost :: fibers :: use_scheduling_algorithm&lt; Priority_scheduler&gt;()用自己的光纤队列创建一个新的Priority_scheduler对象。并且该调度程序与特定于其正在运行的线程的上下文相关联。因此,在我的情况下,当我创建一个新的光纤时,它最终以特定于调用线程的队列(TH2,未运行的th2)纤维)而不是运行我所有纤维的线,Th1。

因此,我放弃了创建一个通过TH2的电话在TH1中运行的纤维的想法。现在,我使用的是从外部线程排队纤维启动请求的队列。纤维线程(TH1)将在执行Scheduler pick_next()函数时检查此队列,如果存在请求,则创建纤维并将其添加到TH1的调度程序队列中。它效果很好 - 尽管我有一个中间队列,我宁愿不拥有(仅出于审美原因)。

I did spend some time looking into this problem. It turns out that executing the command: boost::fibers::use_scheduling_algorithm< priority_scheduler >() creates a new priority_scheduler object with its own fiber queue. And this scheduler is associated with a context that is specific to the thread it is running in. So, in my circumstance, when I created a new fiber it ended up in the queue specific to the calling thread (th2, which wasn't running fibers) instead of the thread that was running all my fibers, th1.

So, I abandoned my idea of creating a fiber to run in th1 by a call from th2. I now using a queue that queues fiber launch requests from external threads. The fiber thread (th1) will check this queue when it executes the scheduler pick_next() function and if requests exist, fibers are created and added to th1's scheduler queue. It works fine--though I have an intermediate queue which I would prefer not to have (for esthetic reasons only).

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