查看原文
其他

为什么多线程编程这么难?

The following article is from 码农的荒岛求生 Author 陆小风

点击关注公众号,一周多次包邮送书

来源:码农的荒岛求生(ID:escape-it)

作者:陆小风

如果你手上有个问题需要用多线程来解决,恭喜,现在你手上有两个问题需要解决了。大家好,我是小风哥,最近项目要上线实在太忙,硬核文没肝出来,今天又是周末,所以聊点轻松的,这个话题就是:为什么多线程编程这么难呢?你有没有想过这个问题。

一边又一边

周末了,美美的睡个懒觉起来做早饭,做饭其实很简单,照着菜谱一步步来就行,没什么难度。在你做饭时突然手机铃声大作,原来是线上出现了故障,其它同事正在排查,需要你协助一下,一边做饭一边打电话应该也不算太难,你可以的。正当你一边排查问题一边做饭时本来约好明天来维修空调的师傅因为协调不开提前一天来了,你不得不一边做饭一边排查问题一边告诉维修师傅哪个空调坏了、问题是啥。。怎么样,是不是开始应付不过来了?这还不算啥,就在这时你约好的同学也到了,一边接待同学一边指挥着维修师傅一边排查问题一边做早饭,你是不是已经开始疯了。
当多线程遇到共享
看到了吧,"多线程"绝不是在编程这个层面很难,多线程本身就很难尤其是当多线程遇上共享数据时更是难上加难,对人类来说,同时做两件互不干扰的事情还是有可能的,一边写代码一边听歌就是,但你可以试试让两个任务共享听的能力,同时听两首歌;或者让两个任务共享大脑的思考能力,一边解bug一边刷算法,你还能轻松加愉快吗?如果你试图推演多线程访问共享数据那么你的脑海很可能就像刚才提到的“一边接待同学一边指挥这维修师傅一边排查问题一边做早饭”,一团糟。。人类的大脑似乎天生就不是很擅长(天才不在此讨论范围),更不用说因解决共享数据而带来的死锁等问题。
遇事不决量子力学
你的多线程代码可能在99.99%的情况下工作正常,但在小概率下就是会有问题,这都不算啥,问题是你该怎么debug呢?你该怎么调试一个可能只有万分之一出错的程序呢?而且更棒的是,就像测不准原理一样,测量这操作本身竟然不可避免的搅扰了被测量粒子的运动状态,因此产生不确定性。当你试图用调试器attach上去又或者加一些log时这本身也会改变多线程程序的行为,或者问题就此不再产生,又或者概率变为了十万分之一,从这个角度看多线程和量子力学有异曲同工之妙这里的根源在于“可能性的组合爆炸”问题。由于操作系统的调度、系统中断再加上程序员添加的锁等原因,我们的程序(线程)总是走走停停,这就导致在程序的“执行空间”上有太多可能,试图去测试每一种可能几乎是不可能的事情,而我们添加一些log等本身就给本来已经爆炸的组合新增一个维度,导致有的问题非常难复现。尽管我们的调试工具IDE等越来越高级,但依然解决不了多线程本身的问题。
性能是个问题
如果你不关心程序性能的话,大可以加上一个很豪迈的锁,但锁也不应该加的过分放飞自我,你能想象为了让北京的某个同学买一本书电商要把整个华北地区的库存锁住吗?如果你关心性能的话那么锁的粒度会是个问题,同时在硬件级别你可能需要了解多核cache一致性以及memory ordering等,这些都不是那么容易理解,更不用提无锁编程,lock-free等等。

·················END·················

推荐阅读

• 他来了!性能吊打 Node.js 和 Deno 的新一代 javaScript 运行时!• 各国开发者薪资水平:中国排名第19位• 从20s优化到500ms,我用了这三招• 低调!又一款百度网盘高速下载神器来了!!• 为什么 Rust 是初创公司的绝佳选择?• 使用USB设备需小心!微软警告高风险蠕虫病毒正在传播• 又一千万级用户APP停运,腾讯:我哭了

👇更多内容请点击👇

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存