哲学家晚餐问题的Haskell求解
最近上课讲到,哲学家晚餐死锁避免,然后发现张凇这里的代码是空白,0Bite,以为是我自己的下载错了,点开第一版源代码,发现:
也是空白,然后第二版的代码好像也没找了,然后找到了神网站http://rosettacode.org/wiki/Rosetta_Code
哲学家晚餐问题全家桶
import Control.Monad
import Control.Concurrent
import Control.Concurrent.STM
import System.Random-- TMVars are transactional references. They can only be used in transactional actions.
-- They are either empty or contain one value. Taking an empty reference fails and
-- putting a value in a full reference fails. A transactional action only succeeds
-- when all the component actions succeed, else it rolls back and retries until it
-- succeeds.
-- The Int is just for display purposes.
type Fork = TMVar IntnewFork :: Int -> IO Fork
newFork i = newTMVarIO i-- The basic transactional operations on forks
takeFork :: Fork -> STM Int
takeFork fork = takeTMVar forkreleaseFork :: Int -> Fork -> STM ()
releaseFork i fork = putTMVar fork itype Name = StringrunPhilosopher :: Name -> (Fork, Fork) -> IO ()
runPhilosopher name (left, right) = forever $ doputStrLn (name ++ " is hungry.")-- Run the transactional action atomically.-- The type system ensures this is the only way to run transactional actions.(leftNum, rightNum) <- atomically $ doleftNum <- takeFork leftrightNum <- takeFork rightreturn (leftNum, rightNum)putStrLn (name ++ " got forks " ++ show leftNum ++ " and " ++ show rightNum ++ " and is now eating.")delay <- randomRIO (1,10)threadDelay (delay * 1000000) -- 1, 10 seconds. threadDelay uses nanoseconds.putStrLn (name ++ " is done eating. Going back to thinking.")atomically $ doreleaseFork leftNum leftreleaseFork rightNum rightdelay <- randomRIO (1, 10)threadDelay (delay * 1000000)philosophers :: [String]
philosophers = ["Aristotle", "Kant", "Spinoza", "Marx", "Russel"]main = doforks <- mapM newFork [1..5]let namedPhilosophers = map runPhilosopher philosophersforkPairs = zip forks (tail . cycle $ forks)philosophersWithForks = zipWith ($) namedPhilosophers forkPairsputStrLn "Running the philosophers. Press enter to quit."mapM_ forkIO philosophersWithForks-- All threads exit when the main thread exits.getLine
然后网站的Haskell上述源代码好像出了点问题,
好吧,其实我也很好奇这个乱码部分的原因是什么,求解。
然后,换个写法吧。
import Control.Concurrent
import Control.Concurrent.STM
import Control.Monad
import System.Randomtype Fork = TVar Bool
type StringBuffer = TChan StringphilosopherNames :: [String]
philosopherNames = map show ([1..] :: [Int])logThinking :: String -> StringBuffer -> STM ()
logThinking name buffer = writeTChan buffer $ name ++ " is thinking..."logEating :: String -> StringBuffer -> STM ()
logEating name buffer = writeTChan buffer $ name ++ " is eating..."firstLogEntry :: StringBuffer -> STM String
firstLogEntry buffer = do empty <- isEmptyTChan bufferif empty then retryelse readTChan buffertakeForks :: Fork -> Fork -> STM ()
takeForks left right = do leftUsed <- readTVar leftrightUsed <- readTVar rightif leftUsed || rightUsedthen retryelse do writeTVar left TruewriteTVar right TrueputForks :: Fork -> Fork -> STM ()
putForks left right = do writeTVar left FalsewriteTVar right Falsephilosopher :: String -> StringBuffer -> Fork -> Fork -> IO ()
philosopher name out left right = do atomically $ logThinking name outrandomDelayatomically $ takeForks left rightatomically $ logEating name outrandomDelayatomically $ putForks left rightrandomDelay :: IO ()
randomDelay = do delay <- getStdRandom(randomR (1,3))threadDelay (delay * 1000000)main :: IO ()
main = do let n = 8forks <- replicateM n $ newTVarIO Falsebuffer <- newTChanIOforM_ [0 .. n - 1] $ \i ->do let left = forks !! iright = forks !! ((i + 1) `mod` n)name = philosopherNames !! iforkIO $ forever $ philosopher name buffer left rightforever $ do str <- atomically $ firstLogEntry bufferputStrLn str
老铁,没毛病,(-_-#.
哲学家晚餐问题的Haskell求解相关推荐
- 博弈论速成指南:那些融入深度学习的经典想法和新思路
选自TowardsDataScience 作者:Jesus Rodriguez 机器之心编译 参与:魔王.杜伟 随着人工智能的发展,博弈论迎来了复兴.关于博弈论,数据科学家需要了解哪些经典思想和新思路 ...
- 深度学习融入博弈论的方法会迸发出哪些新思路呢?
关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 随着人工智能的发展,博弈论迎来了复兴.关于博弈论,数据科学家需要了解哪些经典思想和 ...
- thinking-in-java(21)并发2
think-in-java 并发前半部分(并发1)参见: https://blog.csdn.net/PacosonSWJTU/article/details/104855730 [21.4.3]中 ...
- think-in-java(21)并发
[README] 并发后半部分(并发2,从21.4.3中断开始)参见: https://blog.csdn.net/PacosonSWJTU/article/details/106878087 ; 本 ...
- 利用雅可比方法求线性方程组C语言_【新说】深度学习融入博弈论的方法居然会迸发出这些新思路!...
随着人工智能的发展,博弈论迎来了复兴.关于博弈论,数据科学家需要了解哪些经典思想和新思路呢?本文作者就这些问题一一展开了分析.通过此文,相信读者会对博弈论的概念和分类有更清晰的理解. 博弈论是最让人着 ...
- Haskell语言实现求解一个整数所有因子的代码及运行结果
问题: 求解一个整数的所有因子并输出 代码: factors::Int->[Int]factors n=[x|x<-[1..n],n`mod`x==0] 运行结果:
- 【操作系统】Semaphore处理哲学家就餐问题
"哲♂学家就餐"问题 问题描述 问题分析 关系分析 求解思路 信号量设置 问题解决 方案一 方案二 对比 问题描述 一张圆桌上坐着5位哲学家,每位哲学家之间的桌子上摆一根筷子,桌子 ...
- [2017.02.21-22] 《Haskell趣学指南 —— Learning You a Haskell for Great Good!》
{- 2017.02.21-22 <Haskell趣学指南 -- Learning You a Haskell for Great Good!> 学习了Haskell的基本语法,并实现了一 ...
- Haskell趣学指南4-6
函数的语法 模式匹配 本章讲的就是haskell那套酷酷的语法结构,先从模式匹配开始.模式匹配通过检查数据的特定结构来检查其是否匹配,并按模式从中取得数据. 在定义函数时,你可以为不同的模式分别定义函 ...
最新文章
- 给互联网巨头“搬砖”的人
- java合并整形_java中2个int合并成一个long
- 为什么补码会比原码多一个数
- 近期我们在读的那些优质论文,你不了解下?
- rxjs operator学习笔记
- Exchange性能调优(上)
- 如何实现从wgs-84到beijing54的坐标转换
- 菜鸟也学hadoop(1)_搭建单节点的hadoop
- java struts 读取文件,Struts中读写文件的路径问题
- 移动磁盘显示由于IO设备错误,无法运行此项请求要怎样寻回资料
- 2010-2014总结 ____V_V____ hello-world
- [转载] 使用openpyxl模块向Excel中插入图片
- ubuntu中mysql安装失败
- openstack changePassword
- 产品经理应该扮演的几种角色
- api wke_wke: 基于Webkit精简的纯C接口的浏览器内核,可用于桌面UI、浏览器。
- 2020-12-30 PMP 群内练习题 - 光环
- 鸿蒙os下载到电脑上,华为鸿蒙os系统官网
- 2019第五届中国诗歌春晚致敬先贤
- 用python计算100以内所有奇数的和_用python脚本来计算100以内奇数或者偶数之和
热门文章
- [轉]VS 2010 通过 Architecture创建UML类图设计
- Matlab与Access数据库的连接
- mysql视图改造实体表_数据库视图改了对基表
- Compilation failed: internal java compiler error
- JS 实现 DIV 遍历并随机替换DIV内容
- 05Struts2表单
- nginx——ngx_http_gzip_module
- ajax请求完之前的loading加载
- BZOJ2767:[JLOI2010]足彩投注
- springboot-day01-引入基础