多进程的构架方法

  做了4、5年的开发,大大小小的项目也做了不少,但以前都有一个致命的问题,不知不觉就会写出一个巨大的主 程序出来,层次复杂,编码痛苦,调试困难。但似乎大家都认同这样的开发方式,虽然都知道界面和功能分离是好事情,但就是做不到。我自己也曾痛苦的思考过, 但没有什么收效,似乎在Windows下的开发只能是这么痛苦。

  一星期前买了<<unix编程艺术>>,这一周可谓改天换地,每天都在阅读和思考中度过,想必武侠小说中的武功大进也就是这个意思了。虽然书还没看完,但是有些话实在是不吐不快。

    什么是界面?界面就是功能的子集。没有哪个界面能反映所有的功能,但是若没有界面,对于最终用户来说又是不可忍受的,无论如何都不能指望让一个门卫学会输 入复杂的命令来完成工作,虽然最终用户也包括专业人士,但这世界上终究普通人更多。在这样的前提下,可以认为功能永远比界面更宽泛,更有适应性,而GUI 更狭窄,更具有特殊性,所以将界面和功能进行分拆也就成为一种必然趋势。

   但是如何分拆?在Windows的世界里,一个普遍观点就是DLL。DLL很好,但是还不够好,因为无法直接使用、调试以及升级,带来的问题远比好处 多。另一种方法就是在代码级进行分层,比如GUI一层,功能一层,再用胶合层将二者整合。且不论胶合层的不可复用和调试困难,就一条,如何能做到GUI崩 溃的时候却不影响功能的实现?以前我做过的项目都是这样处理的,直接的后果就是项目越到后期问题越多,代码越不接受变化。调试花费了大量的人力物力,收效 却未必好,功能的一点点小修改就会造成代码里出现意大利面条。你可以说只要前期的小心规划和仔细架构就能避免这些问题,但是谁能准确预测未来?无论做怎样 的努力,你也不能保证现在的功能永远不变,永远不变的恰恰就是变。如果不能保持实现的稳定性和较好的移植性,这样的项目下场一般都不太好。

  说了这么多废话,还是赶紧进入正题。谈谈这一周来的心得体会!

   首先,变化是渐进的,非突变式的。如果能将变化的所在约束在一个比较小的代码范围内,修改就不会成为噩梦。怎么约束?就一个要求:在保证完整性的条件下 让每个模块包含的功能尽量单一和足够小。首先是保证完整性,不是代码足够短,包含的实现足够少就是完整,要达到完整,就要让模块的各个部分做到不可分割和 无需添加,按照古人的说法,就是增一分则太多,减一分则太少。这个要求虽然看起来很好理解,其实并没有什么标准答案,每个人心里都有自己的回答,正所谓仁 者见仁,智者见智。其次是单一化和小型化,一般来说,范围太大的东西会造成人脑覆盖不全,比如一个功能,如果牵扯的部分过多,就会造成从底层到中间层,再 到上层,全部都要思考到,估计没有几个人能做到,即使做到了,将来的维护和修改也会变成噩梦。相反,只要功能的涉及面够窄,就很容易进行思考和修改,这个 道理应该没有什么问题。

  既然要保证模块单一、小型化和保证完整,也就意味着这个模块可以认 为是一个完整而单独的程序,无需外围程序的支持就可以单独运行和测试。从而引出我的最重要的观点:尽量用多进程来分拆程序。在Windows的世界里,多 进程似乎是天生被忽略和鄙视的,从unix的观点看,其主要原因是Windows的设计中对进程的快速创建支持不够,造成对多进程的天然排斥和害怕。但是 换一个思路看,多进程也许是目前最好的架构方式。底层的功能分拆成各个进程单独运行,通过ipc和上层的GUI进行交互,胶合层薄了,移植性增强了,调试 容易了,功能演进也不再成为噩梦。需求永远是渐变的,所以进程的渐变也就成为可控的行为。

    多进程间的传递方式一般有这么几种:共享内存,管道(pipe),信号,消息, socket。其中共享内存适宜于大量数据的即时传递,速度快,容量大。但使用共享内存时需要仔细考虑读写冲突问题,一般的解决办法是用全局锁,但是锁的 存在必然会造成效率的下降,所以能不用锁就尽量不要用。pipe的速度和容量都没有共享内存好,但是用来传递命令和返回值还是很适合的。信号和消息的方式 一般会和操作系统联系紧密,个人不太喜欢。最后是socket,对于异地交互而言,socket是目前很常用的手段,甚至本地进程间通讯也可以使用。但是 由于和网络有关,所以同步性不好保证,需要辩证的使用。

   说了这么多,举个例子说明一下。假设现在要做一套点菜软件供酒店使用,其基本功能包括人员管理,桌台管理,点菜管理,结账以及后台管理五个功能模块。按 照单进程的方式就是将所有功能整合在一起,系统启动时加载所有的功能,一旦某个模块出现问题,则必须重新启动程序,而且各个模块之间很容易发生资源冲突和 请求冲突。如果换成多进程方式,让我们看看有什么不同。首先是所有的功能最终目的地都是数据库,那么可以开发一个后台进程专门所有负责针对数据库的请求, 通过pipe或者共享内存来接收命令和返回结果,那么程序或者说具体代码块之间的接口就是单一的pipe或共享内存了。同时,即使某一个程序运行错误也不 会造成整体失败,只需要重起失败的部分即可。当然了,这种方式下存在一个问题,就是效率的降低,但是对于大多数的应用来说,稳定性的提高远比效率的降低要 重要,而且随着硬件水平的不断提高,效率总是可以达标的。

  数据库处理分拆出去后,剩下的就 很好处理了,人员、点菜、桌台等管理模块都作为单独的后台程序出现,最后GUI部分只需要和各个共享内存和pipe打交道即可,无需只要具体的逻辑处理和 功能实现,而且各个后台程序还可以复用,比如人员管理可以挪到客房服务系统中,甚至是其他系统。GUI随时可以替换,实现了功能和界面的分离,同时系统崩 溃的几率大大降低,升级和售后也方便很多,永远不要把最终用户想的太愚蠢,很多时候人们还是蛮有求知欲的。

  更多的细节需要自己整理,这里只是给出了一个框架,起码我现在的项目已经开始这样做,效果嘛,半年后就知道了。

编程构架包含多种类型,在不同的编程场景中各有特点和应用。 插件式构架编程使用C/C++语言可实现,有经验的编程者可根据自身经验撰写相关文章并给出详细例子。不会写代码仅画UML的构架师,可能缺乏实际操作能力,但特别牛的构架师除外。构架师需要具备写代码的能力,才能更好地进行设计工作 [^1]。 网络应用编程模型中的构架也各有特色。早期计算机网络的数据通信模型有分散式、集中式和分布式。分散式可靠性高,但存在重复存储、不一致性高、成本增加的问题,早被淘汰;集中式硬件成本低,可实现数据共享、资源集中,但响应慢、可靠性低,也早被淘汰;分布式是分散式系统和集中式系统的混合体,其与计算机网络的主要区别是软件而非硬件,在分布式环境中资源以透明的方式供用户使用。C/S模式是胖客户端应用程序编程架构,将一个网络事务处理分为客户端和服务端两部分。客户端为用户提供操作并向网络提供请求服务的接口,服务端负责接收并处理客户端发出的服务请求,将处理结果返回给客户端。C/S既适用于实际应用程序,也适用于计算机部署,从程序实现角度看,是计算机上两个进程的交互,服务端进程逐一等待并处理客户端请求,其应用程序编程模型为面向服务的体系架构(SOA),WCF是具体实现技术之一。B/S模型仅用HTTP进行通信,也被称为web应用程序,采用三层构架,由用户界面、逻辑处理和数据支持构成 [^2]。 在《AI赋能Python零代码编程》专栏的开发环境搭建模块中,涉及Python全栈开发环境搭建,包括Anaconda安装(主要针对Windows平台演示)、Conda虚拟环境管理以实现项目隔离与依赖控制实战,还有常见环境报错排查(如PATH冲突、包版本锁定)。AI编程环境配置方面,有VSCode深度配置(Python扩展、Git集成、主题优化),主流AI编程插件横评(阿里COS、百度Comate、GPT - Copilot)以及插件组合策略(代码补全、实时纠错、智能注释生成) [^4]。 知识图谱搭建构架实践包含信息抽取,如关系抽取,即从文本中识别实体并抽取实体之间的语义关系,获取三元组信息(<主体,谓语,客体>),旨在识别文本中两个或多个实体之间的关系,关系类型有“创立”“所属”“合作”等 [^5]。 ```python # 这里简单示例一个基本的C/S模式的Python代码 # 服务端代码 import socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost', 8888)) server_socket.listen(1) print("Waiting for connection...") conn, addr = server_socket.accept() print(f"Connected by {addr}") while True: data = conn.recv(1024) if not data: break conn.sendall(data) conn.close() # 客户端代码 import socket client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect(('localhost', 8888)) client_socket.sendall(b'Hello, server!') data = client_socket.recv(1024) print(f"Received: {data}") client_socket.close() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值