2012-07-30 76 views
3

我發現boost有一個名爲context的類,用於上下文切換,對吧?boost上下文類

我嘗試谷歌它,但沒有找到任何文件或例子。我只是想知道是否有人可以提供一些信息。

回答

15

Boost :: Context是Boost版本1.51.0及更高版本的官方部分。有關它的信息,請參閱http://www.boost.org/doc/libs/1_51_0/libs/context/doc/html/index.html。不幸的是,文檔是略微不同於實現,有些東西已經在SVN中發生了變化,所以您需要稍微閱讀頭文件。

下面是我寫了一天的例子顯示的boost ::語境下使用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. 
+0

聲明棧在哪裏? – Lucretiel 2013-02-01 15:45:13

+0

@Lucretiel它是類的成員,在代碼中:'std :: array stack;'=) – wjl 2013-02-02 05:57:57

+1

哦。我完全沒有看到滾動條 – Lucretiel 2013-02-04 22:40:49

2

作者的website上的boost-coroutine存檔包含一些基本的文檔和示例,這些文檔和示例都是建立在上下文和上下文本身之上的協程。您還可以在該網站上找到一個光纖套件,至少作爲另一個用例可能很有趣。

+1

謝謝。但是,您提供的鏈接似乎不起作用。 – 2012-08-01 02:10:11

+0

無賴。這個對我有用。請注意,包括基本示例和文檔的上下文到目前爲止已經成爲助推器。如果你不想通過SVN結賬,你也可以在線瀏覽它[這裏](http://svn.boost.org/svn/boost/trunk/libs/context/)。然而,協程和纖維不在樹幹中(但)。 – ingoem 2012-08-01 07:53:40

+1

順便說一句,它似乎在協同和光纖上的活躍發展發生在Oliver Kowalke的[git倉庫](http://gitorious.org/~k-oli/boost-dev/)。 – ingoem 2012-08-01 09:14:39

0

謝謝你的例子代碼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"; 
}