首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用core/异步和go实现Clojure中的睡眠理发师问题

使用core/异步和go实现Clojure中的睡眠理发师问题
EN

Stack Overflow用户
提问于 2022-06-07 16:19:05
回答 1查看 110关注 0票数 1

你好,谢谢您的帮助。我才刚开始学Clojure,我觉得很神奇。下面是我的睡眠理发师问题的密码。我认为从核心/异步中删除缓冲区将是解决这个问题的完美方法,虽然它似乎可以工作,但它永远不会停止。

理发和减掉的缓冲似乎是正确的。

--编辑

,它现在停下来了。但是,我在检查customer是否为nil时遇到了一个错误(我注意到了下面代码中的一行)。似乎它不能在零上做一个if,因为它是0!

代码语言:javascript
运行
复制
(if (not (nil? customer-num)) ;; throws error => Cannot invoke "clojure.lang.IFn.invoke()" because the return value of "clojure.lang.IFn.invoke(Object)" is null

--编辑的末尾

另外,怎样才能得到理发次数的返回值呢?

七周内用七种语言写的睡眠理发师问题。它是由Edsger Dijkstra于1965年创建的。

  • 理发店接待顾客。
  • 顾客到达的间隔是随机的,从10毫秒到30毫秒。
  • 理发店在等候室里有三把椅子。
  • 理发店有一个理发店和一个理发椅。
  • 当理发师的椅子是空的,一个顾客坐在椅子上,叫醒理发师,理发。
  • 如果椅子被占了,所有的新顾客都会离开。
  • 理发需要二十毫秒。
  • 顾客理发后,他起身离开。
  • 确定一个理发师在十秒钟内可以做多少次理发。
代码语言:javascript
运行
复制
(ns sleepbarber
  (:require [clojure.core.async
             :as a
             :refer [>! <! >!! <!! go go-loop chan dropping-buffer close! thread
                     alt! alts! alts!! timeout]]))

(def barber-shop (chan (dropping-buffer 3))) ;; no more than 3 customers waiting

(defn cut-hair []
  (go-loop [haircuts 0]
    (let [customer-num (<! barber-shop)]
       (if (not (nil? customer-num)) ;; throws error => Cannot invoke "clojure.lang.IFn.invoke()" because the return value of "clojure.lang.IFn.invoke(Object)" is null      
        (do (<! (timeout 20))   ;; wait for haircut to finish
            (println haircuts "haircuts!" (- customer-num haircuts) "customers turned away!!")
            (recur (inc haircuts)))
        haircuts))))

(defn operate-shop [open-time]
  ((let [[_ opening] (alts!! [(timeout open-time)
                              (go-loop [customer 0]
                                      (<! (timeout (+ 10 (rand-int 20)))) ;; wait for random arrival of customers
                                      (>! barber-shop customer)
                                      (recur (+ customer 1)))])]
     (close! barber-shop)
     (close! opening)
     )))

(cut-hair)
(operate-shop 2000)
EN

回答 1

Stack Overflow用户

发布于 2022-06-07 17:23:31

如果没有运行代码来确认我的怀疑,我就会发现您的实现有两个问题。

首先,operate-shop的主体以((开始,您似乎打算将其作为分组机制。当然,在Clojure中,(f x y)是如何使用参数x y调用函数f的。因此,您的实现调用了alts!,然后调用了close!,然后调用了shutdown-agents --到目前为止所有这些都是预期的--但是然后用两个零参数调用alts!的结果(这肯定不是一个函数)。所以,一旦你的商店关门,你就应该得到一个ClassCastException。通常,我建议只移除外部的父类,但是由于您使用的是core.async,所以应该用go包装身体,就像在(go x y z)中那样。这是你真正的密码吗?如果您在alts!上下文之外调用go,正如您的代码片段所建议的那样,只能获得运行时错误。

第二种情况是,您的第一个go-loop没有终止条件。您将customer-num视为一个数字,但如果通道关闭,它将为零:这是如何判断一个通道关闭。在减法中使用它应该会抛出某种异常。相反,您应该检查结果是否为零,如果是的话,在商店关闭时退出循环。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72534576

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档