liveBook · Manning

Message passing

As explained in C++ Concurrency in Action, Second Edition

Message passing is a communication technique in which concurrent components exchange information by sending and receiving messages.

Message passing coordinates concurrent components by sending and receiving messages through a messaging subsystem. The subsystem hides synchronization, so components can focus on which messages to handle and send rather than coordinating shared state. section 4.4.2

In the Actor model, discrete actors run on separate threads and communicate through messages; they share no state except information passed directly in those messages. An ATM example uses a state machine on one thread, while its bank and terminal interfaces run separately. section 4.4.2

The ATM example illustrates how message handling drives state transitions:

  • While waiting for a card, the ATM sends a display message and handles a card-inserted message by recording the account and switching to PIN entry. section 4.4.2
  • During PIN entry, it handles digit, clear, and cancel messages; after four digits, it sends a verification request to the bank and changes state. section 4.4.2
Listing 4.15. A simple implementation of an ATM logic class
struct card_inserted
{
    std::string account;
};
class atm
{
    messaging::receiver incoming;
    messaging::sender bank;
    messaging::sender interface_hardware;
    void (atm::*state)();
    std::string account;
    std::string pin;
    void waiting_for_card()                              #1
    {
        interface_hardware.send(display_enter_card());   #2
        incoming.wait()                                  #3
            .handle<card_inserted>(
                [&](card_inserted const& msg)            #4
                {
                    account=msg.account;
                    pin="";
                    interface_hardware.send(display_enter_pin());
                    state=&atm::getting_pin;
                }
                );
    }
    void getting_pin();
public:
    void run()                                           #5
    {
        state=&atm::waiting_for_card;                    #6
        try
        {
            for(;;)
            {
                (this->*state)();                        #7
            }
        }
        catch(messaging::close_queue const&)
        {
        }
    }
};


!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":12,\"ch\":57},{\"line\":12,\"ch\":59}],[{\"line\":14,\"ch\":57},{\"line\":14,\"ch\":59}],[{\"line\":15,\"ch\":57},{\"line\":15,\"ch\":59}],[{\"line\":17,\"ch\":57},{\"line\":17,\"ch\":59}],[{\"line\":28,\"ch\":57},{\"line\":28,\"ch\":59}],[{\"line\":30,\"ch\":57},{\"line\":30,\"ch\":59}],[{\"line\":35,\"ch\":57},{\"line\":35,\"ch\":59}]]"}
!@%STYLE%@!

The listing shows the ATM's card-waiting state and how a received message changes its state. section 4.4.2

How C++ Concurrency in Action, Second Edition covers it

How deep it goes
Explains message handling through ATM state examples and notes that the messaging library hides synchronization.
Examples
Uses an ATM state machine that handles card, PIN, and cancel messages and contacts a bank interface.
What you can do after
Apply message passing by defining which messages a component handles and sends at each state.
How it connects
Connects message passing to the Actor model, state machines, and thread synchronization.

Also explained in

Compare how 9 books explain message passing →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of C++ Concurrency in Action, Second Edition. The section links point to the parts of the book it draws on.