我发现 boost 有一个名为 context 的类,用于上下文切换,对吧?
我尝试用谷歌搜索,但没有找到任何文档或示例。我只是想知道是否有人可以提供一些信息。
我发现 boost 有一个名为 context 的类,用于上下文切换,对吧?
我尝试用谷歌搜索,但没有找到任何文档或示例。我只是想知道是否有人可以提供一些信息。
Boost::Context 是 Boost 1.51.0 及更高版本的官方部分。有关它的信息,请参见http://www.boost.org/doc/libs/1_51_0/libs/context/doc/html/index.html。不幸的是,文档与实现略有不同,并且 SVN 中的某些内容发生了变化,因此您需要稍微阅读头文件。
这是我前几天写的一个例子,展示了 Boost::Context 使用 Boost 1.51.0+最新的 SVN 来制作简单的协程:
#include <array>
#include <functional>
#include <boost/context/all.hpp>
class Coroutine {
public:
Coroutine() :
my_context(boost::context::make_fcontext(
stack.data() + stack.size(),
stack.size(),
Coroutine::dispatch
))
{}
virtual ~Coroutine() {}
void operator()() {
boost::context::jump_fcontext(&yield_context, my_context, reinterpret_cast<intptr_t>(this));
}
protected:
void yield() {
boost::context::jump_fcontext(my_context, &yield_context, 0);
}
virtual void call() = 0;
private:
static void dispatch(intptr_t coroutine_ptr) {
Coroutine *coroutine = reinterpret_cast<Coroutine *>(coroutine_ptr);
coroutine->call();
while (true) coroutine->yield();
}
private:
boost::context::fcontext_t *my_context;
boost::context::fcontext_t yield_context;
std::array<intptr_t, 64*1024> stack;
};
struct A : public Coroutine {
void call() {
std::cerr << "A went to the store one day.\n";
yield();
std::cerr << "A was looking for groceries.\n";
yield();
std::cerr << "A finally found what she was looking for.\n";
}
};
struct B : public Coroutine {
void call() {
std::cerr << "B went to the store one day.\n";
yield();
std::cerr << "B was looking for replacement tires.\n";
yield();
std::cerr << "B didn't find anything at all.\n";
yield();
std::cerr << "B went to another store.\n";
yield();
std::cerr << "B got the tires installed there.\n";
}
};
struct C : public Coroutine {
void call() {
std::cerr << "C went to the store one day.\n";
yield();
std::cerr << "C was looking for USB drives.\n";
yield();
std::cerr << "C found several with competitive pricing.\n";
yield();
std::cerr << "C couldn't decide which to buy, so gave up.\n";
}
};
int main() {
std::cerr << "So, this is what happened.\n";
A a;
B b;
C c;
for (size_t i=0; i<10; ++i) {
a();
b();
c();
}
std::cerr << "Then it all was done.\n";
}
然后编译运行如下:
$ g++ -std=c++11 -o coroutines coroutines.c++ -lboost_context
$ ./coroutines
So, this is what happened.
A went to the store one day.
B went to the store one day.
C went to the store one day.
A was looking for groceries.
B was looking for replacement tires.
C was looking for USB drives.
A finally found what she was looking for.
B didn't find anything at all.
C found several with competitive pricing.
B went to another store.
C couldn't decide which to buy, so gave up.
B got the tires installed there.
Then it all was done.
作者网站上的boost-coroutine存档包含一些基本的文档和示例,用于构建基于上下文的协程和上下文本身。您还会在该网站上找到一个光纤包,至少作为另一个用例可能很有趣。
感谢 wjl 提供您的示例代码。它帮助我理解了 boost context 是如何工作的,以及 boost coroutine 是如何通过 boost context 来实现的。但是你的代码并没有按原样工作,所以我修改它以在 Windows 上编译。(虽然没有检查它是否适用于Linux)
#include <iostream>
#include <array>
#include <boost/context/all.hpp>
class Coroutine {
public:
Coroutine() :
my_context(boost::context::make_fcontext(
stack.data() + stack.size(),
stack.size(),
Coroutine::dispatch
))
{}
virtual ~Coroutine() {}
void operator()() {
boost::context::jump_fcontext(&yield_context, my_context, reinterpret_cast<intptr_t>(this));
}
protected:
void yield() {
boost::context::jump_fcontext(&my_context, yield_context, 0);
}
virtual void call() = 0;
private:
static void dispatch(intptr_t coroutine_ptr) {
Coroutine *coroutine = reinterpret_cast<Coroutine *>(coroutine_ptr);
coroutine->call();
while (true) coroutine->yield();
}
private:
boost::context::fcontext_t my_context;
boost::context::fcontext_t yield_context;
std::array<intptr_t, 64 * 1024> stack;
};
struct A : public Coroutine {
void call() {
std::cerr << "A went to the store one day.\n";
yield();
std::cerr << "A was looking for groceries.\n";
yield();
std::cerr << "A finally found what she was looking for.\n";
}
};
struct B : public Coroutine {
void call() {
std::cerr << "B went to the store one day.\n";
yield();
std::cerr << "B was looking for replacement tires.\n";
yield();
std::cerr << "B didn't find anything at all.\n";
yield();
std::cerr << "B went to another store.\n";
yield();
std::cerr << "B got the tires installed there.\n";
}
};
struct C : public Coroutine {
void call() {
std::cerr << "C went to the store one day.\n";
yield();
std::cerr << "C was looking for USB drives.\n";
yield();
std::cerr << "C found several with competitive pricing.\n";
yield();
std::cerr << "C couldn't decide which to buy, so gave up.\n";
}
};
int main() {
std::cerr << "So, this is what happened.\n";
A a;
B b;
C c;
for (size_t i = 0; i < 10; ++i) {
a();
b();
c();
}
std::cerr << "Then it all was done.\n";
}