Skip to content

Latest commit

 

History

History
234 lines (159 loc) · 4.26 KB

README.md

File metadata and controls

234 lines (159 loc) · 4.26 KB

Boson

Un framework pour la concurrence coopérative

 

 

Copyright JB 2017   —   CC BY-SA 4.0

cppfrug.org / paris / events / 2017-01-19_n14 / Boson

github.com / cpp-frug / paris / events / 2017-01-19_n14 / Boson

L'existant

 

  • Fibres dans folly
  • boost::fiber
  • Raftlib

Inspiré du langage Go

 

  • Fibres au coeur du framework
  • Le netpoller : I/O asynchrone automagique
  • Channels

Pourquoi ?

 

  • Pas d'I/O automagique possible avec l'existant
  • Dépasser la lourdeur des algos "asynchrone"
  • Très bon exercice d'apprentissage

Lancer des fibres

void timer(int out, bool& stopper) {
  while(!stopper) {
    boson::sleep(1000ms);
    boson::write(out,"Tick !\n",7);
  }
  boson::write(out,"Stop !\n",7);
}

void user_input(int in, bool& stopper) {
  char buffer[1];
  boson::read(in, &buffer, sizeof(buffer));
  stopper = true;
}

int main(int argc, char *argv[]) {
  bool stopper = false;
  boson::run(1, [&stopper]() {
    boson::start(timer, 1, stopper);
    boson::start(user_input, 0, stopper);
  });
}

Communiquer entre fibres

boson::run(1, []() {
  boson::channel<int, 1> pipe;

  boson::start([](auto input) -> void {
      int i = 0;
      while (input >> i)
        std::cout << "Received " << i << "\n";
  }, pipe);

  boson::start([](auto output) -> void {
      for (int i = 0; i < 5; ++i) {
        output << i;
        std::cout << "Sent " << i << "\n";
      }
      output.close();
  }, pipe);
});

Sent 0
Received 0
Sent 1
Received 1
Sent 2
Received 2
Sent 3
Received 3
Sent 4
Received 4

Blocage simultané

struct producer {
template <class Duration, class Channel>
void operator() (Duration wait, Channel pipe, int data) const {
  boson::sleep(wait);
  pipe << data;
}
};

int main(int argc, char *argv[]) {
  boson::run(1, []() {
    boson::channel<int, 1> pipe1, pipe2;

    boson::start(
        [](auto in1, auto in2) -> void {
          int result;
          for (int i = 0; i < 2; ++i)
            select_any(
                event_read(in1, result, [&](bool) { std::cout << "Received " << result << "\n"; }),
                event_read(in2, result, [&](bool) { std::cout << "Received " << result << "\n"; }));
        },
        pipe1, pipe2);

    boson::start(producer{}, 500ms, pipe1, 1);
    boson::start(producer{}, 0ms, pipe2, 2);
  });
}

Received 2
Received 1

Blocage simultané hétérogène

int main(int argc, char *argv[]) {
  boson::run(1, []() {
    boson::channel<int, 1> pipe;

    boson::start(
        [](auto in) -> void {
          int result;
          for (int i = 0; i < 2; ++i)
            select_any(
                event_read(0, &result, sizeof(int),
                           [&](ssize_t) { std::cout << "Received on stdin " << result << "\n"; }),
                event_read(in, result,
                           [&](bool) { std::cout << "Received on chan " << result << "\n"; }),
                event_timer(1000ms,  //
                            [&]() { std::cout << "Timeout\n"; }));
        },
        pipe);

    pipe << 2;
  });
}

Retour d'expérience

Les algos lock-free

Le Saint Graal

Queue MPMC wait-free, unbounded, serialisable

Le Saint Graal

Queue MPMC wait-free, unbounded, serialisable

Le Saint Graal

Queue MPMC wait-free, unbounded, serialisable

Le Saint Graal

Queue MPMC wait-free, unbounded, serialisable

Single Producer, Single Consumer

Single Producer, Multiple Consumers

Multiple Producers, Single Consumer

Multiple Produces, Multiple Consumers

Lock-free

versus

Wait-free

Bounded

versus

Unbounded

MPMC

LCRQ (2013)

LCRQ dans Boson

Broken demo time

https://github.com/duckie/boson