百度空间 | 百度首页 
 
查看文章
 
并发相关基本问题【为什么要关注并发、锁】
2009-10-25 21:33
1、为什么要考虑并发?
请看如下命题,我有10个Worker对像,每个对象会发10次言,每次发言时首先会将自己的名字打印在发言内容之前,然后,紧接着会发表发言内容(内容是 10 个字符 g),发言完后换行。(代码请看下面的 并发.Worker 下的 say 方法)

执行结果如下:

Thread0Thread3gggggggggg
Thread3gggggggggg
Thread3gggggggggg
Thread3gggggggggg
Thread3gggggggggg
Thread3gggggggggg
Thread3gggggggggg
Thread3gggggggggg
Thread3gggggggggg
Thread3gggggggggg
Thread1gggggggggg
Thread4gggggggggg
Thread4gggggggggg
Thread4gggggggggg
Thread4gggggggggg
Thread4gThread2gggggggggg
gggggggggg
Thread0gggggggggg
Thread0gggggggggg
Thread0gggggggggg
Thread0gggggggggg
Thread0gggggThread2ggggggggg
Thread1gggggggggg
Thread1gggggggggg
Thread4gggggggggg
Thread4gggggggggg
Thread4gggggggggg
Thread4gggggggggg
Thread4gggggggggg
gggggggggg
ggggg
Thread0gggggggggg
Thread0gggggggggg
Thread0gggggggggg
Thread0gggggggggg
Thread2gggggggggg
Thread1ggThread2ggggggggggggggggg
g
Thread1Thread2gggggggggg
gggggggggg
Thread1gggggggggg
Thread2Thread1ggggggggggggggg
Thread1ggggggggggg
Thread2gggggggggg
Thread2gggggggggggggg

Thread1gggggggggg
Thread2Thread1gggggggggg
gggggggggg
Thread2gggggggggg
成功生成(总时间:0 秒)

看到这个结果(每次执行结果都不同,但基本上不太可能获得理想的每人发言一行的结果),您一定晕了,我靠,他们抢什么抢啊,太不相亲相爱了吧! 不好意思,这就是并发问题的由来。等等,我是搞PHP的,不存在线程啊?确实,PHP不存在线程之说,但是无论是多线程,还是多进程,本质上都是一样的,对数据库中的、缓存中的以及文件中的数据来说,上述的并发问题都一样存在!

请思考如下情况,
您有一个使用积分查看美眉图的页面。当我点击这个页面之后,您页面的某个地方更改了某个代表我积分的$_SESSION 变量(本例以 $_SESSION['code'] 表示),扣掉我的积分,然后做一些清理工作,例如入库啊什么的操作。不好意思,我一直习惯于同时点看N多的连接,同时点击了两个查看美眉图的页面(您单页执行时间20ms的话,可以理解为我20ms内点了多个连接就行了),那么我们从流程上分析会发生生么情。
假定我开始有160分,当A页面开始时,$_SESSION['code'] -= 2 (扣掉了两分,我还有158分,该数据没有真的写入到Session Storage中,Session是当PHP程序终止时或者显示调用session_write_close 时才会写如到storage中的,但无论是否写入storage,都与讨论的结果无关,因为B已经初始化了);与此同时 B 页面也开始了(注意,B页面初始化Session的时候,由于A没有执行完毕,所以A中对我积分的扣除还没写入到storage中,我刚开始仍然是160分),也扣掉了两分(假定不同的MM图积分数是一样的哈);您看,我最终会被扣几分?最终结果是,我只被扣掉了2分!仔细想象,有可能A页面先执行完毕,B页面后完,最终的Session会以B页面写入的数据为准,点完这两个页面后,我还是有158分。如果您还提供免费的页面的话,邪恶的说,可以做到不花一点积分看您的MM图哦(仔细想想流程)。

2、锁
上面的例子真她妈太乱了,能不能让这群人文明点啊!让别人说完再说啊!行,接下来我们开个辩论会好了,给他们加个裁判!裁判同意了才能发言!



谁拿着牌,谁才能发言!嘿嘿,看谁能黑得过谁!执行结果:
Thread0gggggggggg
Thread0gggggggggg
Thread0gggggggggg
Thread0gggggggggg
Thread1gggggggggg
Thread1gggggggggg
Thread1gggggggggg
Thread1gggggggggg
Thread1gggggggggg
Thread1gggggggggg
Thread1gggggggggg
Thread1gggggggggg
Thread1gggggggggg
Thread1gggggggggg
Thread3gggggggggg
Thread4gggggggggg
Thread4gggggggggg
Thread4gggggggggg
Thread4gggggggggg
Thread4gggggggggg
。。。。。
下面省略n行,n次执行,虽然发言着顺序不一样,但总归保证了每个人都能把话说完了吧!目的达到了

类别:默认分类 | 添加到搜藏 | 浏览() | 评论 (3)
 
最近读者:
 
网友评论:
1
2009-10-26 23:07 | 回复
裁判其实就是锁,但锁本身是要消耗性能的,而且其实并不是真正的多线程,程序设计不好,很容易出现性能瓶颈。
我记得facebook团队曾经改进过memcache,让锁的效率提高了40%
 
2
2009-10-29 15:17 | 回复
正确的结果比效率重要得多
 
3
2009-10-30 16:42 | 回复
回复Zhangsilly:他们当然是保证正确的结果的情况的前提下。
 
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu