川川给你洗。。脑之:编程中的状态与并发
大家好,我叫Clyce,大家也可以叫我川川~
今天,是我们的第一节课,在本课中,我们的目标是——
134_3517_cee840f56103f69.jpg
要洗。。。。脑,应该使用磨砂轮的电锯切开头骨,因为磨砂轮切割产生的高温可以使血液迅速凝固,而不会飞溅的到处都。。。
不好意思拿错书了。。。
不闹了,正文开始
让我们先从编程中“状态”的概念讲起。
original_ohGi_61210000133c118d.jpg

说到状态,让我们先来解决一个问题,小明是谁?
original_SrZ3_263500001335125d.jpg 神马?
没错!
让我们来看:
original_wBFI_252e00001338118c.jpg 这个是小明
original_3uGm_6df100001337118e.jpg 。。这个是小明
original_rlxk_24f500001325125d.jpg 。。。。这个是小明
original_2a8r_259200001321118c.jpg 。。。。。这个是小明
large_3ZHu_6ddf0000134a118e.jpg 。。。。。。。这个竟然还是小明
。。。。楼主你究竟想表达什么?
。。。
大家不觉得奇怪吗,有这么多个小明。。?
没关系啊,这些都是同一个小明啊!!!
。。。
那下面这段代码呢:
xiao_ming = new People;
xiao_ming.age = 8;
xiao_ming_2 = new People;
xiao_ming_2.age = 30; //年龄不同怎么可能是同一个对象嘛讨厌!
。。。
那么小明到底是不是小明呢?
上面的图并不是小明,只是小明的一系列照片。
上面的图并不是小明,只是小明某一个时间点的样子。
上面的图并不是小明,小明包含了上面所有的图中描述的小明的集合。
上面所有的图中描述的小明的集合也绝不是小明,小明是这个集合外更大的集合,是任意时刻的小明的总和。
小明也并不是小明,任何人都可以叫做小明。
那么如果小明不是小明,小明到底是谁?
。。
original_LEqG_6012000013b3125b.jpg

。。。
不是讲编程吗!!!怎么讨论哲学问题去了!
。。
讲到编程,那么问题就变成了:
对于传统面向对象语言,对一个事物给出的模型并不能很好的指代事物本身,而是根据上下文,可能分别指代该事物、该事物在某一时刻的快照以及该事物的别名。
于是,为了解决这样一个问题,状态(state)与身份(identity)的理念产生了。
状态即是一个事物在某一特定时空条件下所呈现的样子。
身份即是这个事物本身。
简单的来说,上面的小明中,每一张照片中存储的便是小明的一个状态。
而我们说到小明时想到的,是小明的身份。
那么状态与身份的分离,在许多现代语言(尤其是函数式编程语言)中,就变成了一个要素。
这里就得提到一个东西,不可变数据(immutable data).
数据是不可变的,因为小明无论几岁都是小明。
这里可以做这样一个比对:
//C++............................................
People* grow(People* toGrow) {
++(toGrow-> age);
return toGrow;
}
;Clojure..........................................
(defn grow [to-grow] (update-in to-grow [:age] inc))
这两个代码都创建了一个叫做grow的函数,使一个人的年龄增加了一岁。
但是区别在于,C++版本的grow将这个人的年龄增加后返回这个人,其实返回的是这个人增加一岁后的状态。而原来的状态丢失了。
Clojure版本的grow返回一个年龄增加了一岁的人,而这个人调用此函数之前的自我也能够得以保留。
如果你执行下面的C++
int i;
for (i=0; i<9; i++)
grow(xiaoMing);
你将得到十年后的小明的一个状态。
如果你在Clojure中执行下面代码:
(take 10 (iterate grow xiao-ming))
你就能够得到小明生长十年的十个状态所组成的序列。
那么如果你运行
(iterate grow xiao-ming)
就会得到小明自出生起到时间尽头的每一年的状态
original_3ETs_6e9c00001352118e.jpg 当然你的电脑会先死机。
于是当身份和状态分离之后我们就能够解决小明到底是谁的问题了。
无论沧海桑天,斗转星移,海枯石烂,小明依旧是小明,只是不是原来那个小明了。
。。
original_LEqG_6012000013b3125b.jpg 可是实际编程的时候又有什么用呢?
没错,大多数实际程序是不需要和哲学打交道的,所以immutable data过去并不流行。
事实上immutable data会带来一个非常严重的问题,随着运行时间的增长,程序所使用的内存会不断增长,造成大额度的浪费。(事实上这个问题已经由共享内存技术解决了一部分)
所以,在计算机内存资源宝贵的过去,immutable data这种牺牲空间满足哲学需求的行为并不受欢迎。
可是,现在计算机内存变~~大~~~了~~~呀~~~~~~~~~
。。。决不能发扬这种奢侈浪费精神!
original_zVfS_0645000010521191.jpg

事实上,immutable data的真正意义在与并发程序中,也就是说,在并发程序越来越受重视的年代,immutable要火了。
。。。可是,为什么呢?
我们来打个比方,假设说你是一个动漫画师笔下的二次元生物。
original_VONd_251a0000138b118c.jpg <---现在的你
画师用可变数据的方法作画,
也就是说每画一个你之后,把你擦掉,
画下一个你,并且以直播绘画的方式公布整个动画。
original_DMPQ_5d5900001394118f.jpg <--现在的你
不过画师作画的速度非常快,所以直播也是每秒24帧。
有一天,画师觉得自己老了,力不从心了,找了一个朋友和他一起画你的故事。
于是画师和朋友之间就会出现这样一个局面:
original_xxI5_5d28000013d0118f.jpg

这样固然是不好的,不仅画不成,还可能导致更可怕的事情。。。。。
large_fDum_05af000010341191.jpg

。。。。。那我们应该如何避免呢?
很简单,把带橡皮的笔放在桌子上,谁先抢到谁就画下一幅,另一个人看着。。。。
。。
当然只能有一只笔,否则如果两个人同时拿到了笔,一起在纸上画,甚至一个画的同时另一个擦,就不太好了。
这就是锁机制,这里的笔就是锁。
于是问题圆满解决了。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。吗?
我们假设画师的朋友画完之后忘了把笔放回去,一直握在手里发呆,或者他不停画下一张下一张下一张,那画师就没机会了。。。。。。。
当然更大的问题是下面的情况。。。
“画师的朋友抢到了笔,但是纸在画师那里,画师等待朋友把笔给画师,朋友等待画师把纸给朋友”
然后画师和朋友就一直互相看着等啊等,直到天荒地老。。。
然后就没有然后了。
然后画师和朋友就过上了幸福的生活。
(上面两句就是无视写冲突造成的后果)
那么画师的朋友就必须足够聪明,以至于他能够想到可以把笔先还回去。。。
当然画师的朋友也不必费心提高自己智商,找第三个人坐在旁边,发现这种情况的时候夺下朋友的笔再交给画师就行了。
original_BA94_2f39000013c9125c.jpg

。。。。。。。。难道没有更好的办法了吗??
状态与身份的分离,不可变数据以及以操作为中心的函数式编程让动漫界跨入了一个新时代!
哦,不对,是编程界。。。
immutable data就相当于,画师终于认识到,把你的故事化成本子比画在一张纸上效果好的多。
一帧一帧画成本子的话,只要快速翻页,就能播出一部完整的动画了。
那么画师和朋友如何协作呢?
由于下一帧一定和上一帧有关,所以画师在画下一帧的时候,是要参考上一帧的。这个叫读取。
original_K3Mf_5e88000013df125b.jpg   <--上一帧
于是画师参考上一帧的你开始画下一帧。这个叫做修改。
original_3njc_5d81000013d1118f.jpg <--画师笔下的下一帧
画师画完了,开心地把这一页塞进画册里面。这个叫做提交。
可是翻开画册,他发现朋友抢先一步画完了下一帧,这个叫提交碰撞。
original_7zWp_6e60000013b8118e.jpg   <--朋友笔下的下一帧
于是画师很无奈,只好放弃自己的这一帧画(回滚),根据朋友的画作,开始画更后面一帧,这个叫做重试。
original_BpBC_5f07000013f4125b.jpg

于是,画师和朋友又可以一起画出高质量的动画了。
当然画师和朋友如果是鬼畜动画爱好者的话,大可以完全不管谁先谁后的往里塞,那样效率更高。
同时如果画师的朋友同时还在画番外的话,就不需要因为只有一只笔而没法在画家画主线的时候画番外而苦恼了。
这种技术叫做STM,全称Software Transactional Memory。
不过这里也有个问题:
如果画师的朋友很多很多,或者画师的朋友是个生产力极高的变态,那么画家可能必须重试很多很多很多很多很多很多次。。。。
所以说,良好优化的锁的效率其实高于STM。
可是综合来讲,这种在状态与本质分离下易于实现的并发控制相对来说成本更低些。
完全地,根本地不需要考虑写冲突,死活锁等等问题。。。
不过在这里我需要申明的是,STM并非不能作用于“状态即本质”的编程方式,只是那种编程方式中使用STM会非常混乱和难以驾驭(具体的讨论我就不赘述了,大家可以查阅)
而STM并发所需的真正要素,以及这一要素的优势,将在以后放出~
large_20me_0609000010a21191.jpg

================================================
由于知识的局限性,对STM等概念的了解可能并不十分准确,如有疏漏,诚望指正。
另外,我的博客是www.clyce.net 欢迎大家前来拍砖~
+30  科创币    yanli12321   2012-12-07   太有意思了........
+10  科创币    hackerboygn   2012-12-07   太有爱了
+1  科创币    rb-sama   2012-12-07   有爱~川川已经成为一代宗师了
+2  科创币    20!Dopaminor   2012-12-07   +10000000000000
+25  科创币    城市迷彩_cc   2012-12-07   深入浅出,通俗易懂!!!不顶对不起祖国和人民啊!
+50  科创币    孤独的酒精灯   2012-12-07   这个好
+1  科创币    agckl1456789   2012-12-07   我类个去,您不会是我们微机竞赛老师吧
+20  科创币    科学人   2012-12-07   
+23  科创币    wenrui   2012-12-07   真有爱。。分全给你了
+10  科创币    dr.lc   2012-12-07   轻松易懂!写的太好了!!!
+4  科创币    luo   2012-12-08   这就叫做自我吐槽吗?
+200  科创币    十九   2012-12-08   图文并茂奖
+50  科创币    瞳   2012-12-08   卖你妹的萌
+200  科创币    任某人   2012-12-08   神贴神贴神贴
+1  科创币    隐犬   2012-12-08   哈哈哈~
+25  科创币    逆流的思念   2012-12-29   经典……
+25  科创币    特大号自我   2012-12-30   风格好像What if。。。。
来自:计算机科学 / 软件综合
kesshei
8年5个月前
1楼
哈哈               挺 有内涵的    给力个。
回复
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
cqsrmxxzyx
8年5个月前
2楼
楼主神讲解
回复
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
dr.lc
8年5个月前
3楼
太喜欢了。。。
觉得讲解的太好了!!!
回复
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
逆天
8年5个月前
4楼
赶脚版主中二病全开[s:178]
回复
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
luo
8年5个月前
5楼
这就叫做自我吐槽吗?
回复
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
novakon
8年5个月前
6楼
但是最终为了效率都会弄出cpp的实现然后intel cpp compiler...

不过不管怎样帖子很棒

果壳style
回复
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
lighted
8年4个月前
7楼
顶一个。。。
回复
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
dome
5年6个月前
8楼
帖子很棒,嗯。。。。
回复
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
epi.clyce
学者 机友 笔友
文章
345
回复
2147
学术分
21
2007/07/10注册,2 个月前活动
暂无简介
%7B%22isDisplay%22%3Atrue%7D

仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。

插入资源
全部
图片
视频
音频
附件
全部
未使用
已使用
正在上传
空空如也~
上传中..{{f.progress}}%
处理中..
上传失败,点击重试
等待中...
{{f.name}}
空空如也~
(视频){{r.oname}}
{{selectedResourcesId.indexOf(r.rid) + 1}}
处理中..
处理失败
插入表情
我的表情
共享表情
Emoji
上传
注意事项
最大尺寸100px,超过会被压缩。为保证效果,建议上传前自行处理。
建议上传自己DIY的表情,严禁上传侵权内容。
点击重试等待上传{{s.progress}}%处理中...已上传
空空如也~
草稿箱
加载中...
此处只插入正文,如果要使用草稿中的其余内容,请点击继续创作。
{{fromNow(d.toc)}}
{{getDraftInfo(d)}}
标题:{{d.t}}
内容:{{d.c}}
继续创作
删除插入插入
{{forum.displayName}}
{{forum.countThreads}}
篇文章,
{{forum.countPosts}}
条回复
{{forum.description || "暂无简介"}}
ID: {{user.uid}}
学术分隐藏
{{submitted?"":"投诉或举报"}}
请选择违规类型:
{{reason.description}}
支持的图片格式:jpg, jpeg, png
插入公式
分享回复:{{shareId}}
加载中...
评论控制
加载中...
文号:{{pid}}
加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
加入关注取消关注
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
建议修改
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}
下载资料
{{fileName}}
大小:{{size}}
下载当前附件将花费 {{costMessage}}
{{description}}
你当前剩余 {{holdMessage}}
{{fileName}}
大小:{{size}}
当前附件免费。
你已购买过此附件,下载当前附件不需要花费积分。
加载中...
{{errorInfo}}
附件已丢失
当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}