Muduo 多线程模型:一个 Sudoku 服务器演变

本文通过一个Sudoku Solver服务程序,探讨了并发网络服务的多种设计方案,重点介绍了使用Muduo网络库构建多线程服务器的方法。Sudoku Solver是一个计算密集型任务,适合展示如何利用多核硬件。文章讨论了协议设计、基本实现以及常见的并发服务程序设计方案,如单线程reactor、线程池和多线程reactor模型,并提供了代码示例。
摘要由CSDN通过智能技术生成

陈硕 (giantchen AT gmail)

blog.csdn.net/Solstice

Muduo 全系列文章列表: http://blog.csdn.net/Solstice/category/779646.aspx

本文以一个 Sudoku Solver 为例,回顾了并发网络服务程序的多种设计方案,并介绍了使用 muduo 网络库编写多线程服务器的两种最常用手法。以往的例子展现了 Muduo 在编写单线程并发网络服务程序方面的能力与便捷性,今天我们看一看它在多线程方面的表现。

本文代码见:http://code.google.com/p/muduo/source/browse/trunk/examples/sudoku/

下载:http://muduo.googlecode.com/files/muduo-0.2.5-alpha.tar.gz

Sudoku Solver

假设有这么一个网络编程任务:写一个求解数独的程序 (Sudoku Solver),并把它做成一个网络服务。

Sudoku Solver 是我喜爱的网络编程例子,它曾经出现在《分布式系统部署、监控与进程管理的几重境界》、《Muduo 设计与实现之一:Buffer 类的设计》、《〈多线程服务器的适用场合〉例释与答疑》等文中,它也可以看成是 echo 服务的一个变种(《谈一谈网络编程学习经验》把 echo 列为三大 TCP 网络编程案例之一)。

写这么一个程序在网络编程方面的难度不高,跟写 echo 服务差不多(从网络连接读入一个 Sudoku 题目,算出答案,再发回给客户),挑战在于怎样做才能发挥现在多核硬件的能力?在谈这个问题之前,让我们先写一个基本的单线程版。

协议

一个简单的以 /r/n 分隔的文本行协议,使用 TCP 长连接,客户端在不需要服务时主动断开连接。

请求:[id:]〈81digits〉/r/n

响应:[id:]〈81digits〉/r/n 或者 [id:]NoSolution/r/n

其中[id:]表示可选的 id,用于区分先后的请求,以支持 Parallel Pipelining,响应中会回显请求中的 id。Parallel Pipelining 的意义见赖勇浩的《以小见大——那些基于 protobuf 的五花八门的 RPC(2) 》,或者见我写的《分布式系统的工程化开发方法》第 54 页关于 out-of-order RPC 的介绍。

〈81digits〉是 Sudoku 的棋盘,9x9 个数字,未知数字以 0 表示。

如果 Sudoku 有解,那么响应是填满数字的棋盘;如果无解,则返回 NoSolution。

例子1:

请求:000000010400000000020000000000050407008000300001090000300400200050100000000806000/r/n

响应:693784512487512936125963874932651487568247391741398625319475268856129743274836159/r/n

例子2:

请求:a:000000010400000000020000000000050407008000300001090000300400200050100000000806000/r/n

响应:a:693784512487512936125963874932651487568247391741398625319475268856129743274836159/r/n

例子3:

请求:b:000000010400000000020000000000050407008000300001090000300400200050100000000806005/r/n

响应:b:NoSolution/r/n

基于这个文本协议,我们可以用 telnet 模拟客户端来测试 sudoku solver,不需要单独编写 sudoku client。SudokuSolver 的默认端口号是 9981,因为它有 9x9=81 个格子。

基本实现

Sudoku 的求解算法见《谈谈数独(Sudoku)》一文,这不是本文的重点。假设我们已经有一个函数能求解 Sudoku,它的原型如下

string solveSudoku(const string& puzzle);

函数的输入是上文的"〈81digits〉",输出是"〈81digits〉"或"NoSolution"。这个函数是个 pure function,同时也是线程安全的。

有了这个函数,我们以《Muduo 网络编程示例之零:前言》中的 EchoServer 为蓝本,稍作修改就能得到 SudokuServer。这里只列出最关键的 onMessage() 函数,完整的代码见

评论 52
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值