从线程2在线程1中启动一个boost光纤



我有一个linux主线程(th1),它运行许多使用boost优先级调度器调度的boost光纤。

每隔一段时间,我想从另一个线程(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调用launchFiber函数时,启动代码工作正常,但当我从th2调用它时,它不起作用—看起来光纤没有添加到th1光纤队列中。我在th1 priority_scheduler例程中添加了一个互斥锁来保护光纤队列,但这似乎没有帮助。

在我看来,我真的不明白当有多个线程参与时,光纤系统是如何工作的。我试着看看库的源代码,但它不是很清楚我。

我猜,如果我理解正确,这将是简单的。谁能举个例子告诉我怎么做呢?

与系统线程相反,光纤基于协同调度. 这意味着您应该手动告诉调度器何时可以调度另一个光纤。调度程序可以在这个用户定义的调度点中选择要调度的最佳光纤。. 在这里,调度器将选择具有最高优先级的那个。如果没有具有更高优先级的光纤,那么同一光纤可以恢复的执行。文档说明:

每个光纤都有自己的堆栈。光纤可以保存当前的执行状态,包括所有寄存器和CPU标志、指令指针和堆栈指针,并在以后恢复该状态。其思想是使用协作调度在单个线程上运行多个执行路径(相对于抢占调度的线程)。正在运行的光纤显式地决定何时应该让步以允许另一个光纤运行(上下文切换)。
控件在给定线程上启动的纤维之间协作传递。在给定的时刻,在给定的线程上,最多有一个光纤正在运行。在给定的线程上生成额外的纤维不会将程序分布在更多的硬件内核上,尽管它可以更有效地利用程序运行的内核。

this_fiber::yield()表示对当前光纤执行实际的产率操作。

请注意,如果光纤在线程之间移动(默认情况下不是这种情况),则与线程本地存储不安全兼容,并且使用基本互斥锁/条件变量不安全都可以,特别是如果yield可能出现在受保护代码(临界区)的中间,因为它可能导致死锁。它也可能是次优的,因为互斥锁可能导致当前线程被抢占或被动等待,而另一个光纤可以进行计算。Boost为光纤提供了另一种更安全/更高效的同步机制,尽管人们仍然需要关心这一点。这就是为什么不能使用纤维来盲目地执行任意代码。

要了解更多信息,您可以从最简单的例子开始查看示例。

我确实花了一些时间调查这个问题。事实证明,执行命令:boost::fibers::use_scheduling_algorithm< priority_scheduler >()创建了一个具有自己的光纤队列的新的priority_scheduler对象。这个调度器与特定于它所运行的线程的上下文相关联。因此,在我的情况下,当我创建一个新的光纤时,它最终会进入特定于调用线程的队列(th2,它没有运行光纤),而不是运行所有光纤的线程th1。

因此,我放弃了创建一个通过调用th2在th1中运行的光纤的想法。我现在使用一个队列来对来自外部线程的光纤启动请求进行队列。光纤线程(th1)将在执行调度器pick_next()函数时检查该队列,如果存在请求,则创建光纤并将其添加到th1的调度器队列中。它工作得很好——尽管我有一个中间队列,我不希望有(仅出于美观的原因)。

最新更新