内容来源

使用消息传递框架

有了消息传递框架,接着就是使用框架实现具体的业务逻辑。示例代码实现了一个简单银行业务流程:

  1. 定义消息类型
  2. 定义交互模块
  3. 在模块间传递消息,然后处理

ATM消息类型

...
struct withdraw_ok
{};

struct withdraw_denied
{};

struct cancel_withdrawal
{
  std::string account;
  unsigned amount;
  cancel_withdrawal(std::string const& account_,
                    unsigned amount_):
    account(account_),amount(amount_)
  {}
};

struct withdrawal_processed
{
  std::string account;
  unsigned amount;
  withdrawal_processed(std::string const& account_,
                       unsigned amount_):
    account(account_),amount(amount_)
  {}
};
...

交互模块

示例代码定义了3个交互模块atm、bank_machine、interface_machine,分别代表ATM状态、银行状态、用户状态。

模块间协作

  1. 创建了3个thread对象,分别对应3个不同的模块;
  2. atm会发消息给其他2个模块,所以atm模块获取了bank_machine和interface_machine的队列指针;
  3. 主线程接收用户输入后,通过atm模块发送消息到其他2个模块,最终驱动整个系统运行;

image

int main()
{
  bank_machine bank;
  interface_machine interface_hardware;

  atm machine(bank.get_sender(),interface_hardware.get_sender());

  std::thread bank_thread(&bank_machine::run,&bank);
  std::thread if_thread(&interface_machine::run,&interface_hardware);
  std::thread atm_thread(&atm::run,&machine);

  messaging::sender atmqueue(machine.get_sender());

  bool quit_pressed=false;

  while(!quit_pressed)
  {
    char c=getchar();
    switch(c)
    {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      atmqueue.send(digit_pressed(c));
      break;
    case 'b':
      atmqueue.send(balance_pressed());
      break;
    case 'w':
      atmqueue.send(withdraw_pressed(50));
      break;
    case 'c':
      atmqueue.send(cancel_pressed());
      break;
    case 'q':
      quit_pressed=true;
      break;
    case 'i':
      atmqueue.send(card_inserted("acc1234"));
      break;
    }
  }

  bank.done();
  machine.done();
  interface_hardware.done();

  atm_thread.join();
  bank_thread.join();
  if_thread.join();
}