Concurrency 通勤是如何工作的?

Concurrency 通勤是如何工作的?,concurrency,clojure,Concurrency,Clojure,通勤是如何运作的。 (通勤标识功能和值) Clojure文件中说: 用法:(通勤参考乐趣和参数) 必须在事务中调用。将ref的事务内值设置为: (在ref args的事务值中应用fun)并返回ref的事务值 在事务的提交点,将ref的值设置为: (应用ref args最近提交的值) 因此,通勤形式分两个阶段进行 第二阶段是原子的吗?(应用ref args的最新提交值) 如果没有,本例中会发生什么情况: 2个螺纹(T1和T2) 两者都将增加(交换函数)相同的标识 IDENTITY: (def i

通勤是如何运作的。 (通勤标识功能和值)

Clojure文件中说:

用法:(通勤参考乐趣和参数)

必须在事务中调用。将ref的事务内值设置为:

(在ref args的事务值中应用fun)并返回ref的事务值

在事务的提交点,将ref的值设置为:

(应用ref args最近提交的值)

因此,通勤形式分两个阶段进行

第二阶段是原子的吗?(应用ref args的最新提交值)

如果没有,本例中会发生什么情况: 2个螺纹(T1和T2)

两者都将增加(交换函数)相同的标识

 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。所以,如果我理解正确,通勤操作的最后阶段(提交点)是同步的“锁定通勤乐趣解锁”?