这一次的 QClub 活动是我的老东家山西鑫慧林赞助的,本来打算邀请两位讲师,后来一位来自北京的讲师因为时间和行程问题,最终只邀请到 Tinyfool 一人。不过 Tinyfool 还是很给力的,一口气说了一个半小时,最后意犹未尽的结束演讲。微博上也有朋友戏言,太原一时伞贵啊 http://weibo.com/1400229064/z1najn7yL

这次活动到场将近40人,其中有几位山大的学生,当然还是出现了一些新面孔。本来预定的是一楼的100人会场,但是因为会场工作人员的失误,让我们和另外一个会议冲突了,于是就把我们安排在三楼的大会议室,结果诺大的会议室坐着3、40人显得空空荡荡。在照片中看到人不多,细数下来也将近40人。

Tinyfool 演讲完毕后,赞助商买了不少的啤酒,给 Tinyfool 单独准备了一瓶竹叶青。大家一起喝酒聊天,聊的是不亦乐乎。

Tinyfool 的微博上也分享了他的首次太原之旅 http://weibo.com/1400229064/z1Z5lykVU

 

把基本情况先简述一下,首先是周六太原大雨,影响了到场率,不过还是有将近40人,而且还看到一些新面孔。其次是两位讲师的话题都很给力,演讲都超时,而且QA环节大家都很踊跃的提问。郭振的话题用了1个半小时才结束,张龙的话题更是达到了2个小时。最后5点50结束本次活动。

以下文绉绉的总结出自专业编辑李洋之手:

7月21日,QClub太原站如期在山西出版传媒集团一楼会议室举行,这已经是QClub第三次来到太原举行活动。今天的龙城太原下起雨来,这给炎炎夏季带来了丝丝凉意;而这场期盼已久的QClub技术社区活动对于技术相对滞后的太原地区而言,也是如同久旱逢甘霖一般及时与酣畅。此次活动中,增添了很多新的面孔,他们为QClub太原站社区活动添加了新的血液与活力。

大雨并没有浇灭前来参加活动人们的热情,在不小的会议室当中坐得是满满当当。技术开发人员也都希望在这场难得的“Android应用开发”的主题讲座中汲取自己所需要的养分并希望借此来解决在工作中所遇到的实际问题。好了,我们现在直入主题,看看讲师们今天会给我们分享那些先进理念与经验以及会带给我们哪些意想不到的惊喜!

首先是来自盛大创新院的高级研究员、乐众ROM项目组总架构师郭振分享的 Android 备份框架的架构与设计,以及如何将自己的服务集成到 Android 系统中。此次活动有一点明显地改善就是参与者的积极性与主动性较前两次有了显著地提高。在互动环节当中,参与者与讲师之间的交流更加自然,提问也是更加踊跃,奖品更是抢手……

接下来是联想集团全球应用开发部的高级工程师、InfoQ翻译团队编辑张龙分享的Android跨进程通信机制与AIDL,介绍了Activity与Service之间的通信原理。张龙这个名字,大家一定不陌生,这已经是第二次来到太原与大家分享经验,算是QClub太原站的老朋友了。大家对于张龙刚刚翻译出版的《Android Web应用高级编程》这本书产生了浓厚的兴趣,这本书涉及到一些跨平台移动开发技术的内容。这本书也是作为活动中的奖品来发放,在互动过程中大家的热情都很高涨,很想要获得这本精美IT图书,因此互动问答过程就格外积极与踊跃!

这已经是山西书海数字网络传媒科技有限责任公司第三次成功举办QClub太原站活动了,书海传媒对于推动太原地区IT技术交流,应该说是功不可没。最后,我们还是要再次感谢QClub太原站活动的本地赞助商——书海传媒的鼎力支持。

from 2002-06-14

 

17. May 2012 · Write a comment · Categories: 技术文章 · Tags:

(Source: http://sw1nn.com/blog/2012/04/11/clojure-stm-what-why-how/

Clojure 有很多功能可以帮助在程序中处理并发问题。本文将关注软件事务内存(Software Transactional Memory,缩写 STM),不过这些并发问题的共性都是由多个部分共同运行来得以解决,因此我们期待一些其他思想的渗入……

STM 是什么?

软件事务内存 (STM) 是一种模拟数据库事务的并发控制机制来控制在并行计算时对共享内存的访问控制。它是锁的一种替代机制。

维基百科 – http://zh.wikipedia.org/wiki/软件事务内存

STM 允许在内存中更新多个数据,这些变更对于其他同时在执行相同逻辑的线程来说,显而易见是原子性的。类似数据库中的事务,如果因为某些原因有些更新没有完成,然后就会取消所有更新操作。

一个典型例子就是银行的交易 – 你希望把你的账户中的一些钱转账到我的账户……,我们将使用这个作为我们的例子,因为从概念上来说大家都熟悉。

目前在计算机科学中,STM 的实现还不是一个已经解决的问题,正在进行的研究是怎样更好的完成它。Clojure 选择了一个基于多版本并发控制(MVCC)的方法,MVCC在一个事务中维护多个(逻辑)版本数据的引用。在你的事务执行过程中,你看到的是一份数据的快照,与事务开始时看到的数据是一样的。当你认为在Clojure中普遍使用持久性数据完成你的很多事情,而不需要做太多额外的工作时,MVCC就是一个显而易见的选择。

为什么我们需要 STM?

STM 的核心是 ref 和 dosync,让我们看一个例子……

(def account1 (ref 100))
(def account2 (ref 0))

; to read the current value of a ref, use (deref refname):
;=> (deref account1)
100
;=> @account1 ; @refname is equivalent to (deref refname)
100

(defn transfer [amount from to]
    (dosync
       (alter from - amount)   ; alter from => (- @from amount)
       (alter to   + amount))) ; alter to   => (+ @to amount)

;=> @account1
100
;=> @account2
0
;=> (transfer 100 account1 account2)
100
;=> @account1
0
;=> @account2
100

你们看到我们在这里定义了两个账户,第一个账户 account1 初始化了 100。(transfer) 函数接收一个数量参数amount,一个来源账户 from 和一个目标账户 to,然后使用 alter 修改两个账户,从 from 账户中减去 amount 的数量,添加同样的 amount 数量给 to 账户。这段代码运行在一个单线程中,但是考虑一下,如果还有一个线程在两个 alter 语句之间运行,修改了两个账户中的值,这会发生什么呢?如果没有 STM 的保护,就很容易丢掉其中一个或者两个账户的变更。

另外一个例子;假设在一天结束时,银行希望给所有账户生成一份结算报表。可能这份报表需要很长时间的运行,但是在报表的生成过程中,依然可以对账户交易,并且为了报表目的,我们应该看到的是一致的数据视图。

在 Clojure 中 STM 是怎样工作的

看下面的这张图,你会看到粉色盒子中的三个事务,你也会看到最左边一列中ref值的不同版本。当一个事务通过 (dosync) 开始后,就会获取到ref的版本。获取到的值是在事务执行过程中 (deref) 返回的值(也就是说在事务中读取的ref都是不变的)。

让我们看看最左面的两个事务,两个事务同时开始,同时获取到了相同的 ref 值,因此两个获得的都是 ref 版本为 0 的一份副本。在事务中会执行一些操作,ref 的值将会被更新。第一个(最左面)的事务首先结束,所以赢得了比赛,把 ref 更新为新值。当第二个事务结束时,它尝试写入它的值,但是写失败了(图例中的红色箭头),因为 ref 的版本不是预期的。在这个例子中,事务就重新执行了。注意当事务重新执行时,它首先获得了 ref 新版本的副本,也就是看到的是第一个事务中变更后的值。然后由于没有其他事务尝试更新 ref,这次第二个事务就完成了。

你也看到这一切在进行的同时,第三个事务一直在运行,但是事务的处理过程中没有更新 ref 的值,所以不需要重试事务操作,事务运行完成。

如果保存在 ref 中的值是持久化的数据结构,在内存中保存这些数据结构的多个逻辑版本是很有效率的,因为这些数据结构会共享内部结构。当然,也会使用额外的资源,在一些场景中可能也会出现问题。当定义 ref 时,你还有一些选项来决定在运行时如何管理这些 ref 的历史(也就是上面讨论的这些版本数字)。

; pre-allocate history and limit max-history
(def myref (ref 1 :min-history 5 :max-history: 10))

; supply a function to validate the ref before commit.
(def myvalidref (ref 1 :validator pos?))

这个可以让你通过使用预分配和限制历史资源的使用,来提高在读取-失败中的边界效率。

宽松的一致性和副作用

在一些并发的事例中,你可以放宽松一点,以获得一些的效率。举个例子,假设你要保留一天的交易日志。如果你知道最后的交易结果始终是正确的,你可能就不大关心这些交易的顺序。说实在的,如果你收到两笔分别是 ¥100和¥50的存款,你可能就不在乎它们是被记录为¥100然后¥50,还是¥50然后¥100。存款的两个事务是可交换的,Clojure 也提供了一个并发操作 (commute) 来完成这样的事情……

(defn log-deposit [account amount]
     (dosync
        (println "Depositing $" amount " into account, balance now: "
            (commute account + amount))))

(def myaccount (ref 0))

(log-deposit myaccount 100)
(log-deposit myaccount 50)

; (as good as) equivalent to 

(log-deposit myaccount 50)
(log-deposit myaccount 100)

需要注意 (commute) 的是,当函数调用时,它设置了ref在事务中的值,但是在提交的时候才会真正的做出修改,是通过再次运行传入给 commute 的函数和最新的 ref 值。 这意味着在你的事务中你计算的值可能不是最终提交给 ref 的值。这需要考虑的认真点,你要确保你的操作过程中不依赖最新的 ref 值。

最后,你可能会疑惑上面例子中的 (println),在事务重试的事件中会产生什么副作用呢?会发生一个很简单的副作用。对于上面的例子,这个可能是个不太重要的事情,就是日志将会不一致,但是数据的真实来源将会是正确的。

Clojure 也提供了一个宏,也就是 io!,这个允许你把代码标记为不允许运行在一个事务中。你可以用这个来保护你自己无意中在一个事务里面调用了有副作用的代码。

例如:

(defn log [s]
   (io!
      (println s)))

(log "Hello World") ; succeeds

(dosync (log "Hello World!")) ; throws IllegalStateException

要正确的在一个事务内部完成 IO,你最好从事务内部把消息扔给Agent,Clojure 中的 Agent 是和 STM 整合在一起的,这样当事务成功时就会发送消息,如果事务失败就会被丢弃。

08. May 2012 · 2 comments · Categories: Uncategorized · Tags:

先说这次活动的问题,一定要自我检讨,这次竟然忘记安排摄影师了,最后只有区区可数的几张照片。

再说高兴的事情,本次活动签到人数首次达到53人,这也是从去年7月开始第一次组织活动以来的最高记录。可能也和这次活动的主题《前端开发与用户体验》有关系吧,在太原的设计师多数都是美眉。从现场照片上也能看出,女生比以往的几次活动明显多了,然后……咳咳……人就来的多了。

然后说说讲师吧,分别是来自赞助商快乐妈妈(www.happymama.cn)的设计师赵敏,和来自阿里云的交互设计专家安勇。本地讲师与外地讲师相比,明显在演讲经验和内容的组织上比较欠缺,希望通过以后的活动可以提高本地讲师的演讲水平,也能够让太原的讲师去外地做分享。

这次活动准备的礼品还是比较多的,十本书和二十张2012QCon北京大会资料光盘。依然还是贯彻只要你参与或者与讲师互动,就能获得小礼物的宗旨。到活动的结束,就剩下了5张光盘。基本上都是在阿里云交互设计专家安勇的演讲结束后的提问环节,大家的热情都很高,一口气就发出了20份的礼物,让安勇都有点快招架不住了。

最后的 Open space 环节,与上次相比,稍显冷清了一点。可能因为设计师美眉们好多都提前离场的原因,然后……咳咳……人就走的更多了。

讲一个有趣的小插曲,本地赞助商快乐妈妈(www.happymama.cn)的技术负责人叫安磊,他在接到安勇后做自我介绍。结果安勇以为对方把他的名字记错了,还更正说“不是安磊,是安勇”。

总结,本次QClub太原站参与人数超出了预期,终于摆脱了参与人数倒数第一的帽子,以后一定要继续吸引IT美眉的参与。活动中大家的参与度还是比较高的,可能是大家都很关心这个主题,也可能是因为外地讲师是中韩混血帅哥。忘记安排摄影师了,重大失误。

最后一定要再次感谢赞助商快乐妈妈(www.happymama.cn),谢谢,这次的活动真的真的很成功。

2012 年第一次QClub太原站技术沙龙在山西出版传媒集团一楼会议室

举行,来自太原的数十名软件从业人员参与了此次活动。本次活动的主题是“Spring框架深度剖析”,主讲人有来自联想集团全球应用开发部高级工程师、InfoQ中文站翻译团队编辑张龙,也有太原本土资深软件开发专家和项目经理李永茂。李永茂讲师深入IoC核心实现,剖析了关键的部分源码;还分享了他在架构原理及设计思想方面的独到见解和一些关于Bean的解析问题。接下来,张龙讲师深入浅出地从源码角度揭示Spring 的架构设计与模式的应用;并分析了Spring对AOP的支持与实现方式及Java技术分析等内容。

讲师们的精彩演讲将本次活动频频推向高潮,所有参加活动的听众都认为不虚此行,觉得受益匪浅。在Open Space中,全场的气氛最为轻松活跃,听众们与讲师融为一体,相互交流经验,谈及一些实际工作中遇到的问题。全部活动结束时,天色已经很晚了,听众们仍然意犹未尽,继续讨论着下一次QClub的主题内容和如何将太原的社区活动搞得更加丰富一些。QClub太原站在交流声、掌声、欢笑声中画上了圆满的句号。

最后,再次感谢第一次QClub太原站活动的本地赞助商山西书海数字网络传媒科技有限责任公司的鼎力支持。

–分割线–

  • 上面的文字是赞助商专业编辑写的。
  • 最后 Open Space 环节,大家都忙着聊天忘记拍照片了。