选择遗忘|面试官:这个经典的并发问题用 Go 语言如何实现?
前言:由于 LeetCode Concurrency(并发) 还没有 Go 语言版本 , 我先自行用 Go 语言来解题 。 为了能在 LeetCode 以外的平台获得讨论 , 所以我打算逐渐把自己的解题思路写下 。
本题 LeetCode 链接
本题题目「哲学家吃饭问题」是一个操作系统中的经典问题 , 所以抽象题干我就不再赘述 , 直接说实作要求 。
【选择遗忘|面试官:这个经典的并发问题用 Go 语言如何实现?】The philosophers' ids are numbered from 0 to 4 in a clockwise order. Implement the function void wantsToEat(philosopher, pickLeftFork, pickRightFork, eat, putLeftFork, putRightFork) where:
有几位哲学家 , 他们的 ID 顺时针由 0~4 , 实作一个函式 void wantsToEat(philosopher, pickLeftFork, pickRightFork, eat, putLeftFork, putRightFork) , 其中...
philosopher is the id of the philosopher who wants to eat.
变量 philosopher 代表想要吃饭的哲学家的 ID 。
pickLeftFork and pickRightFork are functions you can call to pick the corresponding forks of that philosopher.
变量 pickLeftFork and pickRightFork 是函式 , 你必须调用他们来使哲学家拿起对应的叉子 。
eat is a function you can call to let the philosopher eat once he has picked both forks.
当哲学家拿起两只叉子后 , 你必须调用 eat 这个函式让哲学家吃一次 。
putLeftFork and pickRightFork are functions you can call to put down the corresponding forks of that philosopher.
变量 putLeftFork and pickRightFork 是函式 , 你必须调用他们来使哲学家放下手中的叉子 。
The philosophers are assumed to be thinking as long as they are not asking to eat (the function is not being called with their number).
假设哲学家们都会思考很久 , 中间都不会要求吃东西(调用函式 thinking() 不必使用哲学家们的 ID)
Five threads, each representing a philosopher, will simultaneously use one object of your class to simulate the process. It is possible that the function will be called for the same philosopher more than once, even before the last call ends.
五个执行绪 , 每一个执行绪代表都一个哲学家 , 用一个类(在 Go 语言是 struct)模拟这个 process 。 这个函式可能被同一个哲学家调用多次 , 甚至在最后一次调用结束前的途中都有可能 。
「叉子」与「筷子」最早课本里都是说「叉子」 。 但我大学上 OS 的时候老师就提过一个疑问:「用叉子吃义大利面 , 一只就够了 , 没必要用到两只吧?所以 , 改成用筷子是不是更合理一点?但没办法 , 谁叫这门学问是西方先发明的?我们就当作筷子吧」 。 于是 , 本文也决定照改 , 以下都用「筷子」代替「叉子」 。
本题考核难点?「拿得起放不下」造成死结、「无限轮回」造成活结饥饿至死在过去的 LeetCode Concurrency 详解中 , 我提到过很多次:
goroutine 若不刻意控制 , 将无法保证执行的先后顺序 , 因此本题就是要考核对 goroutine 顺序控制的能力 。
但前面几题的解法 , 大多是把判断责任中心化 , 方便控管顺序 。 这次 , 与前面几题不同的是 , 这一题要求把判断责任分散到每一位哲学家 thread 身上 , 哲学家彼此之间并不沟通 , 因此很容易发生资源互卡 , 也就是 deadlock 。 本文所示范的 channel 使用方法已经完全避免了死结(deadlock) 。 但这样就没问题了吗?不 , 还有可能发生活结(livelock) 。
推荐阅读
- 窘境|窘境中求助惨遭拒绝!中国此次也选择置之不理,俄国:早该如此
- 五商文化资讯微软选择“沉海”,华为却深藏贵州大山!阿里亚马逊也纷纷布局
- 动力|迈腾,君越,雅阁,凯美瑞之间选择,油耗低动力好,哪款更适合?
- 英超|兰帕德后悔么?放弃他成最差选择,26岁弃将如今是英超黑马缔造者
- 家电消费网| 副总裁:500万用户选择了OPPO的IoT,OPPO发布智能电视
- 网友|面试时话都没讲就赶人走?”,杭州小伙想不通:“就因为家里拆迁了
- 晴晴侃游戏|盗贼和狂暴战谁更适合呢,魔兽怀旧服咸鱼剑近战该如何选择
- 内蒙古|菅义伟第一次出访,为啥选择越南和印尼而不选择美国?
- 网络游戏|魔兽怀旧服咸鱼剑近战该如何选择,盗贼和狂暴战谁更适合呢
- 极客码头|你是选择盒装CPU还是散装CPU?,如果能够节省你装机的预算
