Concurrency Clojure中与STM的并发性

Concurrency Clojure中与STM的并发性,concurrency,clojure,parallel-processing,functional-programming,stm,Concurrency,Clojure,Parallel Processing,Functional Programming,Stm,我目前正在学习Clojure,我不确定如何使用STM实现并发。我试图完成的任务非常简单,我有一个字符串向量,我想在每个字符串上同时运行一个函数,并用函数返回的字符串替换字符串 目前,我可以通过pmap轻松实现这一点: (pmap function string_vector) 如何在Clojure中使用STM实现同样的功能?STM是一种跨线程共享数据的方法。如果您根本不需要协调(在本例中不需要),那么就没有真正的理由使用STM STM是一种跨线程共享数据的方法。如果您根本不需要协调(在本例中不

我目前正在学习Clojure,我不确定如何使用STM实现并发。我试图完成的任务非常简单,我有一个字符串向量,我想在每个字符串上同时运行一个函数,并用函数返回的字符串替换字符串

目前,我可以通过pmap轻松实现这一点:

(pmap function string_vector)

如何在Clojure中使用STM实现同样的功能?

STM是一种跨线程共享数据的方法。如果您根本不需要协调(在本例中不需要),那么就没有真正的理由使用STM

STM是一种跨线程共享数据的方法。如果您根本不需要协调(在本例中不需要),那么就没有真正的理由使用STM

clojure中的STM是关于随着时间的推移保持可变事物的状态。这些事物的状态每时每刻都在变化,因此被称为具有“同一性”。就像你一生都有一个“你”的身份一样,即使三个月大的“你”在120岁时也可能认不出“你”。因此,让我们在您的示例中加入一些可变的内容,以便我们有理由使用STM:

让我们创建一个可公开使用的可变位置来存储字符串,然后在那里并行更改它们:

user> (def current-strings (ref ["a" "b" "c"]))
#'user/current-strings
user> (dosync (alter current-strings (fn [the-string-at-this-instant]
                                       (pmap #(.toUpperCase %) the-string-at-this-instant))))
("A" "B" "C")
user> @current-strings
("A" "B" "C")
user> 
在本例中,我们创建了一个事务,通过对其应用函数来更改字符串集合的状态。在内部,该函数碰巧并行计算新值

为了让这更有趣,让我们制作一个可变事物的向量,然后在一个并行的过程中更新一组独立可变的事物,每个事物在它自己的事务中:

user> (def current-strings [(ref "a") (ref "b") (ref "c")])
#'user/current-strings

user> (doall
       (pmap (fn [ref-to-update]
               (dosync (alter ref-to-update #(.toUpperCase %))))
             current-strings))
("A" "B" "C")

user> (map deref current-strings)
("A" "B" "C")
user> 

正如您所看到的,这些都不需要STM,因为所有这些操作都可以通过clojure中的其他可变类型来处理,atoms将是一个不错的选择。和裁判一起比赛也很有趣!玩得开心

clojure中的STM是关于随着时间的推移保持可变事物的状态。这些事物的状态每时每刻都在变化,因此被称为具有“同一性”。就像你一生都有一个“你”的身份一样,即使三个月大的“你”在120岁时也可能认不出“你”。因此,让我们在您的示例中加入一些可变的内容,以便我们有理由使用STM:

让我们创建一个可公开使用的可变位置来存储字符串,然后在那里并行更改它们:

user> (def current-strings (ref ["a" "b" "c"]))
#'user/current-strings
user> (dosync (alter current-strings (fn [the-string-at-this-instant]
                                       (pmap #(.toUpperCase %) the-string-at-this-instant))))
("A" "B" "C")
user> @current-strings
("A" "B" "C")
user> 
在本例中,我们创建了一个事务,通过对其应用函数来更改字符串集合的状态。在内部,该函数碰巧并行计算新值

为了让这更有趣,让我们制作一个可变事物的向量,然后在一个并行的过程中更新一组独立可变的事物,每个事物在它自己的事务中:

user> (def current-strings [(ref "a") (ref "b") (ref "c")])
#'user/current-strings

user> (doall
       (pmap (fn [ref-to-update]
               (dosync (alter ref-to-update #(.toUpperCase %))))
             current-strings))
("A" "B" "C")

user> (map deref current-strings)
("A" "B" "C")
user> 

正如您所看到的,这些都不需要STM,因为所有这些操作都可以通过clojure中的其他可变类型来处理,atoms将是一个不错的选择。和裁判一起比赛也很有趣!玩得开心

我明白。我只是想知道,为了学习。我很难理解STM,任何帮助都将不胜感激。@Pythoner,仅仅因为它是为了“学习目的”,并不意味着它就没有意义。你的问题就像说“我有一架飞机。我怎样才能用它来学习驾驶(汽车)?”当然,你可以在高速公路上滑行你的飞机。但是,如果你真的开车,你一点也不知道——它们是完全不同的机器,有着完全不同的预期用途,而且控制方式也不同。我理解。我只是想知道,为了学习。我很难理解STM,任何帮助都将不胜感激。@Pythoner,仅仅因为它是为了“学习目的”,并不意味着它就没有意义。你的问题就像说“我有一架飞机。我怎样才能用它来学习驾驶(汽车)?”当然,你可以在高速公路上滑行你的飞机。但是你对实际驾驶一辆汽车一点也不明智——它们是完全不同的机器,具有非常不同的预期用途,并且控制方式也不同。在这里要小心。因为pmap和map一样是懒惰的,所以你不应该仅仅评估它的副作用,如果你想确保所有的结果都能实现的话,你应该强制整个过程。如果您没有在repl中打印此内容,那么这些更改都不能保证发生(事实上,由于分块,只有前32个更改会发生)。注意重复的32英寸。很好!“懒虫”潜伏在这附近。我在里面放了一个
doall
。同样值得注意的是,如果你把dosync放在pmap之外,它就不起作用了。您正在对一个字符串调用doall,这是一个不可操作的操作。再次,在包含32个以上元素的对象上尝试它,而不将结果打印到repl以查看它是否正确。你需要做所有pmap的结果,而不是它里面的任何东西。我完全在没有实际测试示例的情况下加入了它,我现在将正确地修复它。谢谢你让我保持诚实。这里要小心。因为pmap和map一样是懒惰的,所以你不应该仅仅评估它的副作用,如果你想确保所有的结果都能实现的话,你应该强制整个过程。如果您没有在repl中打印此内容,那么这些更改都不能保证发生(事实上,由于分块,只有前32个更改会发生)。注意重复的32英寸。很好!“懒虫”潜伏在这附近。我在里面放了一个
doall
。同样值得注意的是,如果你把dosync放在pmap之外,它就不起作用了。您正在对一个字符串调用doall,这是一个不可操作的操作。再次,在包含32个以上元素的对象上尝试它,而不将结果打印到repl以查看它是否正确。你需要做所有pmap的结果,而不是它里面的任何东西。我完全在没有实际测试示例的情况下加入了它,我现在将正确地修复它。谢谢你让我保持诚实。我已经投票决定结束这一切。这个问题不是适定的,因为它在th中没有要求