求教保证C++程序长期稳定运行的技术手段

zhcosin 2014-03-15 02:14:49
本人从事后台服务器程序开发工作,服务程序需要每年365天每天24小时不间断工作,程序若崩溃退出对于用户是无法接受的,在此想请教一下各位有哪些保证程序长年累月运行不会出问题的技术?
1. 目前程序申请动态内存都是用的默认的分配器new,这样长期下去会不会造成大量的内存碎片?
2. 关于生产者消费者问题的缓冲区有没有必要限定最大长度,以免任务过多导致程序死掉?
3. 定时器有没有办法避免它过多的定时任务?
4. 现在程序里线程管理有点乱,好些地方都在开线程池,有没有良好的可控制的线程管理方法?
...全文
358 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
DM306 2014-03-16
  • 打赏
  • 举报
回复
C++程序的绝对稳定性很难很难做到,在趋向上很大程度取决于架构的设计和程序员的经验。如果代码规模较小,可以按设计原则进行重构,如果太大,就只能做一些补救性措施:1.编写内存池统一管理内存,一次性申请整个程序所需内存,使用时指针标记,释放时只去指针标记,而不释放;2.编写线程池统一管理线程的创建和回收;3.尽最大可能进行代码复用,减少可出错的可能;4.建立守护进程,实时监控如遇异常则提前告警或进行一系列快速自修复;5. 定期自动维护,可以设在系统空闲时段做全面自检或重启动;6.建立备份机制,保证在系统出现问题时有备份系统可短时提供服务;7.分析使用数据,按照客户使用习惯做重点检测并优化。
仙境之桥2046 2014-03-16
  • 打赏
  • 举报
回复
4. 现在程序里线程管理有点乱,好些地方都在开线程池,有没有良好的可控制的线程管理方法? 增加线程,不是有缩容的处理吗?
zhcosin 2014-03-16
  • 打赏
  • 举报
回复
引用 8 楼 qq120848369 的回复:
1. 目前程序申请动态内存都是用的默认的分配器new,这样长期下去会不会造成大量的内存碎片? 这个肯定是有碎片的,程序跑久了就会变慢,cpu不太平稳,可以用开源的tcmalloc,jemalloc内存池解决,不需要做代码改动。 2. 关于生产者消费者问题的缓冲区有没有必要限定最大长度,以免任务过多导致程序死掉? 这个看业务选择,淘汰策略一般就是fifo,有一种做法就是装不下的写到文件fifo里,每个文件限制装N条,文件满就创建个新的继续往里写,文件名就是按当前文件名序号最大的+1去创建就可以了。 读的时候就是从最小序号的文件读,可以单独启一个线程去定时check磁盘fifo,有内容就取1条出来处理,这样内存就可控了。 3. 定时器有没有办法避免它过多的定时任务? 定时器看实现,比如你用平衡树或者小根堆做的定时器,在定时任务特多的时候插入肯定会变慢。 linux内核里的时间轮定时器就没有这种顾虑,插入是O(1)的。 4. 现在程序里线程管理有点乱,好些地方都在开线程池,有没有良好的可控制的线程管理方法? 各功能点顾好自己的线程就行了,彼此也没什么影响。 比较好的方法是抽象一个全局共享的线程池,你给它一个callback+arg,它在线程里回调处理,这样各业务都可以共用这个线程池了。
灰常灰常感谢,尤其你提到的tcmalloc和jemalloc,原来都是好东西。
qq120848369 2014-03-16
  • 打赏
  • 举报
回复
1. 目前程序申请动态内存都是用的默认的分配器new,这样长期下去会不会造成大量的内存碎片? 这个肯定是有碎片的,程序跑久了就会变慢,cpu不太平稳,可以用开源的tcmalloc,jemalloc内存池解决,不需要做代码改动。 2. 关于生产者消费者问题的缓冲区有没有必要限定最大长度,以免任务过多导致程序死掉? 这个看业务选择,淘汰策略一般就是fifo,有一种做法就是装不下的写到文件fifo里,每个文件限制装N条,文件满就创建个新的继续往里写,文件名就是按当前文件名序号最大的+1去创建就可以了。 读的时候就是从最小序号的文件读,可以单独启一个线程去定时check磁盘fifo,有内容就取1条出来处理,这样内存就可控了。 3. 定时器有没有办法避免它过多的定时任务? 定时器看实现,比如你用平衡树或者小根堆做的定时器,在定时任务特多的时候插入肯定会变慢。 linux内核里的时间轮定时器就没有这种顾虑,插入是O(1)的。 4. 现在程序里线程管理有点乱,好些地方都在开线程池,有没有良好的可控制的线程管理方法? 各功能点顾好自己的线程就行了,彼此也没什么影响。 比较好的方法是抽象一个全局共享的线程池,你给它一个callback+arg,它在线程里回调处理,这样各业务都可以共用这个线程池了。
zhcosin 2014-03-16
  • 打赏
  • 举报
回复
引用 6 楼 xx306 的回复:
C++程序的绝对稳定性很难很难做到,在趋向上很大程度取决于架构的设计和程序员的经验。如果代码规模较小,可以按设计原则进行重构,如果太大,就只能做一些补救性措施:1.编写内存池统一管理内存,一次性申请整个程序所需内存,使用时指针标记,释放时只去指针标记,而不释放;2.编写线程池统一管理线程的创建和回收;3.尽最大可能进行代码复用,减少可出错的可能;4.建立守护进程,实时监控如遇异常则提前告警或进行一系列快速自修复;5. 定期自动维护,可以设在系统空闲时段做全面自检或重启动;6.建立备份机制,保证在系统出现问题时有备份系统可短时提供服务;7.分析使用数据,按照客户使用习惯做重点检测并优化。
谢谢你的意见, 1. 关于使用内存池的问题,我觉得由内存池在启动时一次性申请好程序所需内存,这个一方面由于程序所需内存虽然大多数时候是比较稳定的,但在业务繁忙时段可能还是需要申请新的内存(当然这不是问题),另一方面内存池运行一段时间后也会产生内存碎片而导致无法满足程序新的内存使用请求,无非是把操作系统所面临的问题转嫁给了程序的内存池,所以我觉得,使用内存池更多的是性能上的好处,对于稳定性似乎没多大帮助,而且这个要求程序的内存池至少要比默认的内存分配器要稳定。
没事人 2014-03-15
  • 打赏
  • 举报
回复
我好像没有发言权因为我才刚入门
zhcosin 2014-03-15
  • 打赏
  • 举报
回复
怎么没几个人回应呢?
zhcosin 2014-03-15
  • 打赏
  • 举报
回复
引用 1 楼 truelance 的回复:
电信设备都是365*24小时的 1. 关键的单板(服务器)都是有备份的, 1+1主备或者资源池方式。使用无损的主备倒换技术。 2. 专用的单板/虚拟机,也就是一个服务器上只运行指定的程序(集),不会运行其它程序 3. 很多程序使用固定的内存分配,也就是程序一启动就按最大规格申请好所有内存,运行中不会再有内存申请或释放 4. 定制的多线程框架防止死锁,对超出框架限制的用法需要经过专家评审 5. 实时的指标跟踪和无损的热补丁升级。运行维护是高可用性的一部分,不要指望一次性把代码写完善。 6. 大投入的测试体系。
谢谢你,不过你说的都是客户所能采用的技术手段,我想要的是开发人员在软件设计方面的技术手段。
熊熊大叔 2014-03-15
  • 打赏
  • 举报
回复
电信设备都是365*24小时的 1. 关键的单板(服务器)都是有备份的, 1+1主备或者资源池方式。使用无损的主备倒换技术。 2. 专用的单板/虚拟机,也就是一个服务器上只运行指定的程序(集),不会运行其它程序 3. 很多程序使用固定的内存分配,也就是程序一启动就按最大规格申请好所有内存,运行中不会再有内存申请或释放 4. 定制的多线程框架防止死锁,对超出框架限制的用法需要经过专家评审 5. 实时的指标跟踪和无损的热补丁升级。运行维护是高可用性的一部分,不要指望一次性把代码写完善。 6. 大投入的测试体系。

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧