对于我来说,很难想出一个现实世界的并发示例:
想象一下上面的情况,那里有许多车道,许多路口和大量的汽车。此外,还有一个人的因素。
这个问题对于交通工程师来说是一个艰苦的研究领域。当我一段时间前调查它的时候,我注意到很多模型都失败了。当人们谈论函数式编程时,我往往会想到上面的问题。
你能在Haskell里模拟吗?Haskell真的这么并发吗?在Haskell中,并行化这种并发事件的限制是什么?
发布于 2009-04-12 23:36:03
我不知道问题到底是什么。Haskell 98没有为并发指定任何内容。特定的实现,如GHC,提供了实现并行性和并发性的扩展。
为了模拟交通,它将取决于你需要从模拟中得到什么,例如,如果你想要跟踪单个汽车,或者用一般的统计方法,你是否想要使用滴答或连续的时间模型等等。从那里,你可以得到你的数据的表示,它本身可以用于并行或并行评估。
GHC提供了几个方法来利用多个硬件执行单元,从传统的信号量和互斥量到带有轻量级线程的频道 (可以用来实现像Erlang这样的演员模型 )、软件事务存储器、纯功能并行表达式评价、战略和实验嵌套数据并行。
所以是的,Haskell有许多并行执行的方法,这些方法当然可以用于流量模拟,但是在选择最佳的数字表示来进行并发模拟之前,您需要清楚地知道您想要做什么。每种方法都有自己的优点和局限性,包括学习曲线。您甚至可能会了解到,对于模拟的规模而言,并发性是过分的。
发布于 2009-04-15 17:18:41
在我看来,你是在做模拟,而不是现实世界的并发。这类事情通常使用离散事件模拟来解决。几年前,我在Haskell做了类似的事情,并在延续单变压器的基础上建立了自己的离散事件模拟库。恐怕它是我的雇主所有的,所以我不能邮寄,但并不太难。延续实际上是一个挂起的线程,因此定义如下(从内存中):
type Sim r a = ContT r (StateT ThreadQueue IO a)
newtype ThreadQueue = TQ [() -> Sim r ()]状态内的ThreadQueue保存当前计划线程的队列。您还可以使用其他类型的线程队列来保存未调度的线程,例如在信号量中(基于"IORef (Int,ThreadQueue)")。一旦您有了信号量,您就可以构建相当于MVars和MQueues的内容了。
若要调度线程,请使用"callCC“。"callCC“的参数是一个函数"f1”,它本身以一个函数"c“作为参数。这个内部参数"c“是延续:调用它将恢复线程。当您这样做时,从线程的角度来看,"callCC“只是返回作为参数给"c”的值。实际上,您不需要将值传递回挂起的线程,因此参数类型为null。
因此,您对"callCC“的参数是一个lambda函数,它接受"c”,并将其放在适合您执行操作的任何队列的末尾。然后,它从国家内部获取ThreadQueue的首脑,并调用它。您不需要担心这个函数的返回:它永远不会返回。
发布于 2009-04-12 22:46:59
如果您需要一种具有功能顺序子集的并发编程语言,请考虑Erlang。
关于Erlang的更多信息
https://stackoverflow.com/questions/742552
复制相似问题