Welcome

首页 / 软件开发 / C++ / Muduo 多线程模型之一个 Sudoku 服务器演变

Muduo 多线程模型之一个 Sudoku 服务器演变2014-04-03 陈硕 本文以一个 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

< p>响应: 693784512487512936125963874932651487568247391741398625319475268856129743274836159/r/n

 

< p>例子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 个格子。