埃尔兰的哲学家餐厅

2023-12-22

如果您以前看过《哲学家就餐》,那么您就会知道有几种方法可以做到这一点。我的实现创建了与消息传递进行通信的哲学家和分叉进程。

我有很多关于分叉和哲学家进程格式的程序,但我自己弄清楚了,现在我将分享完成的代码。我是初学者仅供参考。祝你今天过得愉快。

-module(df).
-export([start/0, fork/2, philosopher/5]).

start() ->
SpawnForks = spawnForks([1,2,3,4], []),
SpawnForks2 = lists:reverse(SpawnForks),
main(SpawnForks2, [], 1).


%Creates a list of spawned fork processes
spawnForks([], ForkList) -> ForkList;
spawnForks([Head|Tail], ForkList) ->
  Fork = spawn(df,fork,[Head, "down"]),
spawnForks(Tail, [Fork|ForkList]).


%Philosopher 4 will have a different fork order
main(ForkList, PhilList, Count) when Count =:= 4 ->
  Fork1 = lists:nth(Count, ForkList),
  Fork2 = lists:nth(1, ForkList),
  %arguments to the philosopher: (Count = PhilosopherNumber, 2 = number of times to eat, fork1, fork2, self
  Philosopher = spawn(df, philosopher, [Count, 2, Fork1, Fork2, self()]),
  await([Philosopher|PhilList], ForkList);

  %philosophers 1-3 will have standard fork order.
main(ForkList, PhilList, Count) ->  
  Fork1 = lists:nth(Count, ForkList),
  Fork2 = lists:nth(Count + 1, ForkList),
  %arguments to the philosopher: (Count = PhilosopherNumber, 2 = number of times to eat, fork1, fork2, self
  Philosopher = spawn(df, philosopher, [Count, 2, Fork2, Fork1, self()]),
  Count2 = Count + 1,
main(ForkList, [Philosopher|PhilList], Count2).


%await waits for philosophers to be done and shuts down the fork processes
await([],[])-> ok;
await([],[Head|Tail]) -> 
    Head ! {shutdown}, await([], Tail);
await([Pid|Rest], ForkList)->
    receive {done, Pid} ->
    await(Rest, ForkList)
end.



%a fork process
%when state == down, accept pickup messages. After receiving a pickup request, 
%send an authorization. Print "fork up", and set fork State to up.
fork(Fork,State) when State =:= "down" ->
receive 
    {shutdown} -> exit(normal);
    {pickup, Pid, Philosopher} -> 
    io:format("Philosopher ~p picks up Fork ~p.\n",[Philosopher,Fork]),
    Pid ! {getfork, self()},
fork(Fork,"up")
    end;
%when state == up, accept putdown messages. After receiving a putdown request, 
%send an authorization. Print "fork up" and set fork State to up.
fork(Fork,State) when State =:= "up" ->
    receive
    {shutdown} -> exit(normal);
    {putdown, Pid, Philosopher} ->
    Pid ! {takefork, self()},
    io:format("Philosopher ~p puts down Fork ~p.\n",[Philosopher,Fork]),
fork(Fork,"down")
end.



%a philosopher process 
philosopher(_, Times, _,_, Main) when Times =:= 0 -> Main ! {done, self()}, exit(normal);
philosopher(Philosopher, Times, Fork1, Fork2, Main)->  
    io:format("Philosopher ~p is thinking.\n",[Philosopher]),
%request fork pickups on adjacent forks. wait for authorization messages and print "eating" 
    Fork1 ! {pickup, self(), Philosopher},
    receive 
    {getfork, Fork1} ->
                Fork2 ! {pickup, self(), Philosopher}
    end,
    receive         
    {getfork, Fork2} -> 
                io:format("Philosopher ~p is eating.\n",[Philosopher]),
                Fork1 ! {putdown, self(), Philosopher},
                Fork2 ! {putdown, self(), Philosopher},
                receive
                {takefork, Fork1} -> ok;
                {takefork, Fork2} -> ok
    end,
                Times2 = Times - 1,
philosopher(Philosopher, Times2, Fork1, Fork2, Main)
    end.

我立刻注意到两件事:

  1. 您有多个未终止的receive块——即,没有end匹配。请参阅 Erlang/OTP 文档here http://erlang.org/doc/reference_manual/expressions.html#id78524.
  2. 你可能有非法警卫。您可能想看看简单的术语比较是否适合您,而不是 string:equal。请参阅 Erlang/OTP 文档here http://erlang.org/doc/reference_manual/expressions.html#id81912.

最后,我知道复制并粘贴到 Stackoverflow 问题中很容易,而不必担心格式,但如果您的编辑器屏幕看起来与上面的代码类似,您可能希望为您的首选编辑器安装 Erlang 语言支持。缩进可以成为你的朋友。 :-)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

埃尔兰的哲学家餐厅 的相关文章

  • 在 Windows 上编译 Erlang 代码

    我安装了 Erlang 13B 并尝试按照教程进行操作 每次我到达c tut 我得到一个错误而不是 ok tut 所以看起来没有安装任何模块 有人能指出我正确的方向吗 我尝试过 Emacs 但我真的不知道如何使用它 甚至还没有接近让 Erl
  • 如何在没有任何服务器的情况下创建 P2P 网络聊天?

    有没有一种方法可以在没有任何服务器的情况下创建 P2P 网络聊天 可以 但是您必须决定见面地点 如果你的朋友把他的IP发给你 你就可以连接 那么你只需要告诉更多的人加入即可 一段时间后 你会变得越来越大 然后 如果网络上的某个链接发生故障
  • 随机排列列表中的元素(随机重新排列列表元素)

    我的程序的一部分要求我能够随机洗牌列表元素 我需要一个函数 当我给它一个列表时 它会伪随机地重新排列列表中的元素 安排的改变Must每次通话时都可以看到相同的列表 我的实现似乎工作得很好 但我觉得它相当长 并且正在增加我的代码库 而且 我有
  • 为什么使用erts_debug:size/1时atom的内存为零?

    I use erts debug size 1计算erlang VM中atom的内存 但我发现输出为零 谁能解释一下原因 7 gt erts debug size true 0 原因是原子与原子的数据一起保存在原子表中 因此整个节点中只有一
  • Erlang 17推荐使用地图替换记录,但是如何让mnesia支持地图?

    在 joe 的 Erlang 的重大改变 中http joearms github io 2014 02 01 big changes to erlang html http joearms github io 2014 02 01 big
  • Node.js 或 Erlang

    当谈到它们可以处理的并发级别时 我真的很喜欢这些工具 Erlang OTP 看起来是更稳定的解决方案 但需要更多的学习和深入研究函数式语言范例 看起来 Erlang OTP 在多核 CPU 方面做得更好 如果我错了 请纠正我 但我应该选择哪
  • Erlang 参与者与 OOP 对象有何不同?

    假设我有一个 Erlang actor 定义如下 counter Num gt receive From increment gt From self new value Num 1 counter Num 1 end 同样 我有一个 Ru
  • Erlang 更好地支持哪种数据库(SQL)?

    你建议我在 Erlang 中使用什么 MySQL 还是 Postgres 哪个数据库有更好 更成熟 更稳定 更快 的 Erlang 驱动程序 The Erlang ODBC 接口 http erlang org doc apps odbc
  • 当通过 basho rebar 从命令行运行 Erlang 应用程序时,如何设置 Erlang 节点名称

    我已经使用 basho rebar 编译了我的 Erlang 应用程序 它生成了一个独立的 escript 可执行文件 我从命令行运行它 如下所示 myapp myconfig config 我的问题是如何确定运行我的应用程序的 Erlan
  • 如何限制Erlang VM(BEAM)使用的核心数量?

    我正在具有 2 个四核 Xeon E5520 2 2GHz 24 0GB RAM 和 Erlang R15B02 启用 SMP 的节点上运行实验 我想知道是否可以限制Erlang VM使用的核心数量 以便我可以暂时禁用一些核心并逐步增加数量
  • Erlang:如何将原子转换为字符串?

    我想从原子转换为字符串 Input hello world Output hello world 我该如何实现这一目标 Use atom to list http erlang org doc man erlang html atom to
  • 如何在 Erlang 中将数字转换为单词?

    我发现了一个关于将数字转换为 单词 的有趣问题 代码高尔夫 数字到单词 https stackoverflow com questions 309884 code golf number to words 我真的很想看看你如何在 Erlan
  • 在 digraph_utils:is_acirclic/1 返回 false 后查找循环或循环

    我怎样才能 有效地 在Erlang有向图中找到循环或循环digraph utils is acyclic 1返回假 EDIT is acyclic is 定义为 https github com erlang otp blob maint
  • 在 Erlang 中实现图灵机

    我有一个小项目 与实现图灵机非常相似 我遇到的基本问题是保存当前配置 例如头部的位置和更多信息 对我来说特别重要的是保留头部位置以使其向前或向后移动 Erlang 解决这个问题的方法是什么 我是 Erlang 新手 但据我探索 OTP ge
  • Erlang 中的函数链

    最好创建像 Active Record 或 Hibernate 这样的 ORM 它应该像这样处理链式查询 User User new for login stackoverflow admin for password 1984 load
  • 调用函数时Erlang“未绑定变量”

    我正在尝试将整数参数 N 传递给cake并返回一个大小为 N 的 2 的平方列表 为了示例 例如面包店 蛋糕 3 gt 4 4 4 这是我到目前为止所做的尝试 module bakery export cake 1 Foo fun X gt
  • Erlang 中的静态类型检查

    我慢慢地爱上了 Erlang 但只有一个很大很大的问题 我非常喜欢 Standard ML 和 ocaml 等语言 它们具有强大的静态类型检查功能 有没有一种好的 干净的方法来在 erlang 中引入某种静态类型检查 我正在看 type a
  • Erlang++ 运算符。语法糖,还是单独操作?

    是Erlang的 运算符只是语法糖lists concat或者这是完全不同的操作 我试过搜索这个 但不可能通过谷歌搜索 并得到任何有用的东西 这就是如何lists concat 1在 stdlib lists 模块中实现 concat Li
  • 如何在 Ubuntu Karmic 上安装 LFE?

    Erlang 已经安装 dpkg l grep erlang ii erlang 1 13 b 3 dfsg 2ubuntu2 Concurrent real time distributed function ii erlang appm
  • Erlang:到 Python 实例的端口没有响应

    我正在尝试通过 Erlang 端口与外部 python 进程进行通信 首先 打开一个端口 然后通过 stdin 将消息发送到外部进程 我期待在进程的标准输出上得到相应的答复 我的尝试如下所示 open a port Port open po

随机推荐

  • 我想在Linux上删除多行文本

    像这样 Before 1 19 22 abcde 2 19 23 3 19 24 abbff 4 19 25 abbc After 1 19 22 abcde 3 19 24 abbff 4 19 25 abbc 我想删除没有字母表的部分
  • 带有嵌入式码头的 Web 应用程序给出例外

    我正在尝试使用 Java 7 和 Jetty 9 1 3 维护一个使用嵌入式 jetty 独立运行的 java web 应用程序 除了 JSP 页面之一中的所有链接之外 所有内容都会运行 该页面上的每个链接都应该获取 png 文件或文本文件
  • 正则表达式忽略捕获的中间部分

    我想要一个正则表达式 当应用于 第一第二第三 时将匹配 第一第三 在单个组中 即在 C 中 Match Value将等于 firstthird 那可能吗 我们可以忽略后缀或前缀 但是中间呢 匹配以 first 开头 具有零个或多个其他字符
  • 如何在 Sencha Touch 中销毁非活动视图

    我遇到了一个我认为非常重要的问题 在一个简单的 Sencha Touch 应用程序中 我有很多视图 我的主视图是一个底部带有停靠图标的选项卡面板 有时在我的应用程序中 我会切换到选项卡面板之外的另一个视图 我不希望 DOM 因视图而超载 我
  • Spring Boot 与 Hibernate 在使用 H2 数据库启动时生成删除约束错误

    我正在使用 spring boot 并有一个像这样配置的 H2 数据库 在 application properties 中 spring datasource url jdbc h2 mem AZ DB CLOSE DELAY 1 DB
  • PHP:在共享主机上使用 browscap.ini。 - ini_set() 失败

    我正在尝试使用 get browser 不幸的是我的页面位于共享主机上 并且我无法访问 php ini 我已经下载了最新版本的 browscap ini 并将其放置在我的文档根目录中 然后我添加了以下内容 if ini set browsc
  • 是否绝对需要手动配置 IIS6 才能使用 ASP.NET MVC?

    我有一个虚拟主机回复我 无法更改 IIS6 设置来设置 mvc 到 Asp Net ISAPI dll 的映射 也无法启用通配符应用程序映射 简而言之 我无法更改任何 IIS 设置 有没有办法在这种情况下运行 ASP NET Mvc Not
  • 让 SSIS 检测 csv 文件的列大小

    我正在尝试使用 SSIS 将 csv 文件导入到 SQL 中 但遇到了一个基本缺陷 SSIS 似乎确定所有字段都是 varchar 50 即使它正确识别了逗号分隔符 当我尝试将数据发送到 SQL 中的表时 这会导致问题 有没有办法让它认识到
  • Google 地图 v2 Projection.toScreenLocation(...) 非常慢

    我已在 Android 应用程序中将 Google 地图 v1 升级到 v2 v2 很好 等等 但有一种方法似乎是我一生中最慢的事情 Projection proj map getProjection Point point proj to
  • Rails has_one 与连接表

    在我的应用程序中有Athletes 运动员可以有很多运动项目 Athlete has many sports through gt user sports has one primary sport conditions user spor
  • 编写简单语言的解析器

    我正在尝试设计一种类似于嘴唇 模式的简单语言 我已经写了它的词法分析器 tokenizer 我可以分为运算符 标识符等 但我现在尝试编写解析器 对于这一点 我只举一个例子就足够了 有人可以给我一个java代码的例子吗 此外 每个人都提到了a
  • 如何处理 scss 项目中的部分内容?

    以下问题 在我的服务器上 我在主目录中有一个 style scss 文件 我使用sass watch style scss style css style compressed因此每次编辑 style scss 时都会创建一个新的 styl
  • 如何获取 SharePoint 工作流中的参数

    我正在尝试创建一个带有输出参数的自定义工作流程操作以进行错误处理 根据各种示例 我无法让 Parameter Direction Out 工作 一切似乎都正确 但当我尝试将输出分配给 SharePoint Designer 中的 错误 变量
  • Windows:如何查询低级键盘挂钩中修饰键的状态?

    对于 USB 键盘配置工具 我需要拦截所有键盘输入并检测同时按下哪些修饰键和普通键 因此 我使用 Windows 低级挂钩 WH KEYBOARD LL 它工作正常 只是我无法确定 WIN 键 VK LWIN VK RWIN 是否被按下 c
  • 如何为未知长度的输入字符串分配内存?

    这是结构 typedef struct friend char firstname char lastname char birthdate 9 friend 我对如何让用户输入字符串并将其放置在friend结构为firstname or
  • SSIS 2012 未找到方法:无效

    最近 当我想打开 OLE DB 源组件时 我在每个 SSIS 包 使用 Visual Studio 2012 中都遇到此错误 Method not found Void Microsoft DataTransformationService
  • Mono / Ubuntu - 定义冲突

    我正在尝试在 Ubuntu 上构建一个库 Medsphere Widgets 但它抛出了一个错误 我已经进行了很好的搜索 但似乎没有人能找到答案 配置脚本工作正常 并且完成时没有警告或错误 当我去运行 make 时 它 会执行以下操作 po
  • 复制项目行为不一致?

    考虑这个目录结构 C temp A file txt C temp B 如果我运行命令 Copy Item C temp A C temp B A Recurse Force ErrorAction Stop I have C temp A
  • 如何在 Google Dialogflow Fullfilment 内联编辑器中安装 npm 包

    我想在我的聊天机器人中安装一些 npm 包 但我无法使其工作 package json 文件如下所示 name dialogflowFirebaseFulfillment description This is the default fu
  • 埃尔兰的哲学家餐厅

    如果您以前看过 哲学家就餐 那么您就会知道有几种方法可以做到这一点 我的实现创建了与消息传递进行通信的哲学家和分叉进程 我有很多关于分叉和哲学家进程格式的程序 但我自己弄清楚了 现在我将分享完成的代码 我是初学者仅供参考 祝你今天过得愉快