Lecture 6

SFR1811·2022년 1월 27일
0

3.9 Semi-Coroutine Example

3.9.1 Same Fringe

Fringe is the leaf nodes order sensitive.
How can you determine if two trees have same Fringe?

The best way is to take advantage of coroutine stack to represent iterator of secondary tree.

template<typename T> class Btree{
  struct Node {...}; ... // other members
  _Coroutine Iterator{
    Node * cursor;
    void walk(Node * node){ // walk tree
     if(node == nullptr) return;
      if(node->left == nullptr && node->right == nullptr) { // leaf node
        cursor = node;
        suspend();
      }else{
        walk(node->left);
        walk(node->right);
      }
    }
    void main() {walk(cursor); cursor = nullptr;}
   public:
    Iterator(Btree<T> & btree): cursor(&btree.root){}
    T * next(){
      resume();
      return cursor;
    }
  };
  ... // other members
};

3.9.3 Producer-Consumer

Consumer consumes as Producer produces something.

_Coroutine Consumer {
  int p1, p2, status; bool done;
  void main() { // starter prod
    // 1st resume starts here
    int money = 1;
    for ( ; ! done; ) {
      cout << "cons " << p1 << " "
           << p2 << " pay $"
           << money << endl;
      status += 1;
      suspend(); // activate delivery or stop
      money += 1;
    }
    cout << "cons stops" << endl;
  } // suspend / resume(starter)
 public:
  Cons() : status(0), done(false) {}
  int delivery( int p1, int p2 ) {
    Cons::p1 = p1; Cons::p2 = p2;
    resume(); // activate main
    return status;
  }
  void stop() { done = true; resume(); } // activate main
};

_Coroutine Producer{
  Cons & c;
  int N;
  void main() { // starter ::main
    // 1st resume starts here
    for ( int i = 0; i < N; i += 1 ) {
      int p1 = rand() % 100; // products
      int p2 = rand() % 100;
      cout << "prod " << p1
           << " " << p2 << endl;
      int status = c.delivery( p1, p2 );
      cout << " stat " << status << endl;
    }
    c.stop();
    cout << "prod stops" << endl;
  } // suspend / resume(starter)
 public:
  Prod( Cons & c ) : c(c) {}
  void start( int N ) {
    Prod::N = N;
    resume(); // activate main
  }
}

Note that Producer never suspend(), so Producer doesn't need to be a coroutine.

When you run out off the main() of Coroutine, you go to the starter coroutine instead of the last resumer.

Usually starter and the last resumer are the same coroutine, but there are some cases where these two are different.

profile
3B CS

0개의 댓글