boost上下文类

boost context class

本文关键字:上下文 boost      更新时间:2023-10-16

我发现boost有一个名为context的类,用于上下文切换,对吧?

我试着用谷歌搜索它,但没有找到任何文档或例子。我只是想知道是否有人能提供一些信息。

Boost::Context是Boost 1.51.0及以上版本的官方部分。看见http://www.boost.org/doc/libs/1_51_0/libs/context/doc/html/index.html有关它的信息。不幸的是,文档与实现略有不同,SVN中的一些内容也发生了变化,因此您需要稍微阅读头文件。

下面是我前几天写的一个例子,展示了使用Boost1.51.0+最新SVN:制作简单协程的Boost::Context

#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协同程序档案包含一些基于上下文的协同程序和上下文本身的基本文档和示例。您还会在该网站上找到一个光纤包,这可能很有趣,至少作为另一个用例。

感谢wjl提供的示例代码。它帮助我理解了boost上下文是如何工作的,以及boost协程是如何通过boost上下文实现的。但是你的代码不能正常工作,所以我修改了它,让它在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";
}