我一直在阅读很多关于Scala和Erlang如何处理轻量级线程及其并发模型(actor)的内容.
但是,我有疑虑.
Scala和Erlang是否使用类似于Java(绿色线程)使用的旧线程模型的方法?
例如,假设有一个具有2个内核的机器,那么Scala/Erlang环境将为每个处理器分叉一个线程?其他线程将由用户空间(Scala VM/Erlang VM)环境调度.它是否正确?
在引擎盖下,这是如何工作的?
Clojure STM(dosync)方法和Java同步Block有什么区别?
我正在阅读"睡觉的理发师"问题下面的代码.(http://www.bestinclass.dk/index.clj/2009/09/scala-vs-clojure-round-2-concurrency.html)
(defn the-shop [a]
(print "[k] entering shop" a)
(dosync
(if (< (count @queue) seats)
(alter queue conj a)
(print "[s] turning away customer" a))))
Run Code Online (Sandbox Code Playgroud)
为了避免竞争条件,dosync使用,所以我问自己"Java同步块有什么区别(STM)"?它会阻止这个关键代码吗?
提前致谢 !丹塔斯
我是Scala的新手(Scala代码运行器版本2.7.7.final),我真的不明白为什么当我们使用高阶函数时它需要调用者提供参数类型.
在下面的示例中,我有一个独立的对象(Util),它有一个函数.但是在Main块中,调用者必须将参数类型传递给匿名函数.
为什么Scala不从Array类型(即String)中推断出函数的类型?有没有办法做到这一点?
object Util {
// Just for fun! Suppose that the arrayOne and arrayTwo are all the same length.
// will swap the elements from arrayOne to ArrayTwo.
def swap[T](arrayOne:Array[T], arrayTwo:Array[T] , f:(T,T) =>(T,T)) {
for(i <- 0 until (arrayOne.length min arrayTwo.length)){
val (left, right) = f(arrayOne(i),arrayTwo(i))
arrayOne(i) = left
arrayTwo(i) = right
}
}
}
object Main extends Application {
val arrayOne = Array("A","B","C")
val arrayTwo = …Run Code Online (Sandbox Code Playgroud) 真正的通勤方式.(通勤身份功能和价值观)
Clojure文档说:
用法:(通勤ref fun&args)
必须在事务中调用.将ref的in-transaction-value设置为:
(应用有趣的in-transaction-value-of-ref args)并返回ref的in-transaction-value.
在事务的提交点,将ref的值设置为:
(应用最近最具承诺价值的参考args)
因此,通勤形式分两个阶段进行.
是第二阶段原子?(应用最近最具承诺价值的参考args)
如果没有,在这个例子中发生了什么:2个线程(T1和T2).
两者都会增加(交换功能)相同的身份.
IDENTITY: (def i (ref 0 )
(dosync (commute inc i ) )
Run Code Online (Sandbox Code Playgroud)
通勤呼叫inc的第一步中的T1,其中ref i = 0(在事务值= 1)
T1停止
通勤调用inc的第一步中的T2,ref i = 0(在事务值= 1)
T2停止
第二步中的T1再次调用inc,最近提交值i = 0,inc函数返回但更新前ref(i)T1停止
第二步中的T2再次使用最近的提交值i = 0调用inc并更新引用
T1再次启动并使用inc返回值= 1更新引用
这是竞争条件问题?如何避免这种情况?如果第二阶段是原子的,那就不会发生.
提前致谢
更新:如果我理解正确的通勤操作(提交点)的最后阶段是同步"LOCK通勤乐趣UNLOCK**"?
关于C指针的技巧问题.请阅读下面的代码段并尝试解释列表值更改的原因(此问题基于此代码):
tail具有列表的内存地址.
如何在下面更改可能的列表?
typedef struct _node {
struct _node *next;
int value;
}Node;
int main(){
Node *list, *node, *tail;
int i = 100;
list = NULL;
printf("\nFirst . LIST value = %d", list);
tail =(Node *) &list;
node = malloc (sizeof (Node));
node->next = NULL;
node->value = i;
//tail in this point contains the memory address of list
tail->next = node;
printf("\nFinally. LIST value = %d", list);
printf("\nLIST->value = %d", (list->value));
return 0; …Run Code Online (Sandbox Code Playgroud)