多线程并发总结五 CSP

CSP本身是一套数学语言,用来描述Process以及Process之间的通讯的。当一个Process使用数学语言描述了出来,我们就可以对其进行数学推导简化和分析,比如研究会不会发生死锁和进入发散无序状态等等。

既然CSP可以用来分析多线程的,那么计算机语言也提供了对应的支持。

其中支持得最好的就是Golang,它是我理解的第一只对CSP提供语言原生支持的语言。其中协程就是CSP中的Process,Channel就负责实现CSP中的Process通讯。在程序逻辑层面代码还是同步的,碰到Process通讯的时候还是会把当前的Process阻塞住的,但是在Golang协程本身的阻塞并不会阻塞住线程,所以还是可以理解成一种异步的实现方式。

Java从JDK7开始也引进了一个java.util.concurrent.Exchanger。它可以实现线程之间的通讯,但是因为Java没有原生对协程的支持,所以它还是一个阻塞线程的解决方案。虽然用了Exchanger,Java的代码可以写成CSP的方式,但是如果在高并发的情况下还是会消耗大量的线程。

CSP的情况下还是可能会出现死锁的,虽然它的引起原因已经不是对锁的获取顺序有关了,而是不同的Process的通讯出现了问题。

FOOLCUST = (in2p → large → FOOLCUST | in1p → large → FOOLCUST)

上面是使用CSP描述了一个有问题的名叫Fool Customer的Process,希望投入一便是或者两便是都能获得一块大的巧克力。

VM = (in2p → large → VM | in1p → small → VM)

上面描述的是一个正常的自动售卖机Vender Machine,只有投入两便是才能提供大块的巧克力,一便是可以提供的只有小的巧克力。这样的两个Process如果合并在一起通讯,就会出现Deadlock,FOOLCUST触发了in1p之后,因为large一直没有发生,所以它就卡在那里了。

 

你可能感兴趣的:(多线程和并发)