Concurrency 通勤是如何工作的?
通勤是如何运作的。 (通勤标识功能和值) Clojure文件中说: 用法:(通勤参考乐趣和参数) 必须在事务中调用。将ref的事务内值设置为: (在ref args的事务值中应用fun)并返回ref的事务值 在事务的提交点,将ref的值设置为: (应用ref args最近提交的值) 因此,通勤形式分两个阶段进行 第二阶段是原子的吗?(应用ref args的最新提交值) 如果没有,本例中会发生什么情况: 2个螺纹(T1和T2) 两者都将增加(交换函数)相同的标识Concurrency 通勤是如何工作的?,concurrency,clojure,Concurrency,Clojure,通勤是如何运作的。 (通勤标识功能和值) Clojure文件中说: 用法:(通勤参考乐趣和参数) 必须在事务中调用。将ref的事务内值设置为: (在ref args的事务值中应用fun)并返回ref的事务值 在事务的提交点,将ref的值设置为: (应用ref args最近提交的值) 因此,通勤形式分两个阶段进行 第二阶段是原子的吗?(应用ref args的最新提交值) 如果没有,本例中会发生什么情况: 2个螺纹(T1和T2) 两者都将增加(交换函数)相同的标识 IDENTITY: (def i
IDENTITY: (def i (ref 0 )
(dosync (commute inc i ) )
通勤呼叫inc第一步中的T1,参考i=0(事务值=1)
T1站
参考i=0的通勤呼叫inc第一步中的T2(事务值=1)
T2站
在第二步中,再次调用inc,使用最近的提交值i=0,inc函数返回,但在更新ref(i)T1之前停止
T2在第二步中再次调用inc,使用最近的提交值i=0并更新引用
T1再次启动并使用inc返回值=1更新引用
这是一个竞赛条件问题?clojure如何避免这种情况?
如果第二阶段是原子的,这将不会发生
提前谢谢
更新:
如果我正确理解通勤操作的最后阶段(提交点)是同步的“锁定通勤乐趣解锁**”关键是要认识到ref的事务内值(由通勤产生)实际上可能不同于在提交点最终写入ref的值 在您的示例中,线程T1和T2同时运行它们的事务,i指的是0。他们都(包括i)通过通勤,因此在他们的交易中都看到i=1。但是,当它们准备提交时,通勤(inc)中指定的函数将使用最近提交的值应用于ref。所以如果T1先提交,i=1,然后T2提交,i=2。在回答您的问题时,这些提交确实是原子性的,因此不可能存在任何竞争条件 我引用以下通勤文件: 在事务的提交点,将ref的值设置为:
(应用ref args最近提交的值)
因此,乐趣应该是可交换的,否则,您必须接受wins行为中的最后一个。
“wins中的最后一个”位警告您,如果您正在应用的函数不是可交换的——我想到了矩阵乘法——那么事实上,一个竞争条件是可能的。即,首先提交的事务将其功能应用于“原始”ref值,下一个提交的事务将其功能应用于更新状态。但是,函数应用程序仍以原子方式应用。关键是要认识到ref的事务内值(由通勤产生)实际上可能不同于在提交点最终写入ref的值 在您的示例中,线程T1和T2同时运行它们的事务,i指的是0。他们都(包括i)通过通勤,因此在他们的交易中都看到i=1。但是,当它们准备提交时,通勤(inc)中指定的函数将使用最近提交的值应用于ref。所以如果T1先提交,i=1,然后T2提交,i=2。在回答您的问题时,这些提交确实是原子性的,因此不可能存在任何竞争条件 我引用以下通勤文件: 在事务的提交点,将ref的值设置为:
(应用ref args最近提交的值)
因此,乐趣应该是可交换的,否则,您必须接受wins行为中的最后一个。
“wins中的最后一个”位警告您,如果您正在应用的函数不是可交换的——我想到了矩阵乘法——那么事实上,一个竞争条件是可能的。即,首先提交的事务将其功能应用于“原始”ref值,下一个提交的事务将其功能应用于更新状态。不过,函数应用程序仍以原子方式应用。Nice Michaelle。所以,如果我理解正确的话,通勤操作的最后阶段(提交点)是同步的“锁定通勤乐趣解锁”?很好的Michaelle。所以,如果我理解正确,通勤操作的最后阶段(提交点)是同步的“锁定通勤乐趣解锁”?