我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。
这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。
这几天sleep上了热搜,其实我不太关心这些,具体咋回事我也不懂,不是我的领域。
有人提到一个观点:“sleep多数时候多意味着逻辑和时间有过于紧密的耦合关系。90%的情况下,这个耦合关系都是错的,需要被耦合的不是时间,而是其他要素。”(@Piglei)。
他还解释道:“米饭一般来说会在半小时内被煮熟。如果你想吃饭,本质不是要‘等半小时’,而是要(通过某种途径)确认‘饭熟了’这件事。万一饭煮到一般停电了呢?”。
我对此观点深以为然啊。
最近几个月我一直在给硬件设备写程序,硬件设备限制比较多,有较多的地方使用了sleep,但是我心里清楚,所有的sleep都不是最佳方案。
例1 sleep(30s)等待设备初始化
设备启动后执行用户程序的时候设备还没有完全初始化,比如4G模块还没有初始化,不能获取SIM的ICCID(这是系统写入到一个文件的),网络组件尚不可用,相关调用会异常,所以启动脚本先sleep(30s),系统各部分应该就准备好了,用户程序才能正常运行。
这个方案是有效的,但是,也是不可靠的。
比如某种原因导致系统超过30秒还没有完全启动怎么办?程序需要知道的确是不是“30秒”,而是系统究竟什么时候初始化完成。下面的两个方案可能会更好:
- 系统知道自己什么时候准备好,然后再调用用户程序
- 用户程序检查系统状态,根据系统状态做不同处理
第一个方案有点困难,因为那部分我控制不了。再说了,4G网络状态、SIM卡插拔都是不可预期的,所以程序里面多做一些处理是应该的。
假设系统一切正常、出错就重启设备,这样简单粗暴就能解决90%的问题,但是如果生产的量很大,小概率问题也会变经常,维护起来就头疼了。第二个方案就是比较复杂,要写很多一般用不上的代码。
例2 用sleep来控制发送给MQTT的速度
借助MQTT发送大数据的时候,由于MQTT服务器的限制,必须拆成多个包,还必须控制速度保证暂存在MQTT服务器的数据量不超过限制,这同时还受到了接收方的处理速度的限制。一旦有包被丢弃整个传输就失败了。
所以我用了sleep来控制发送速度,这个方案迄今为止都工作得很好。但是很显然,这也是偷懒方案,理想的方案是,通过应答确认来控制,再加上滑动窗口控制……这就有点重新实现TCP协议的味道了。
有时候我们选择了妥协,但心里要清楚这是妥协,不能理直气壮
第一个例子我已经在代码里解决了一部分,程序逻辑复杂了,但减少了因为某种特定情形陷入无限重启的故障。
第二个例子我就不打算改了,因为这个东西目前只是个自己用的辅助工具,有问题随手改代码了。如果可能升级为正式工具,再说吧。