当前位置: 首页 > 知识库问答 >
问题:

Clojure Async/Go如何停放阻塞代码

邓季
2023-03-14

我使用一些Java库来实现非异步的get和post请求。我曾经把这样的请求包装到未来,它为我解决了“等待问题”(我的意思是等待响应)

(defn unchangeable-lib-request [n]
  (Thread/sleep 1000)
  n)

(defn process [n]
  (let [res (atom [])]
    (dotimes [i n]
      (future (swap! res conj (unchangeable-lib-request i))))
    (loop []
      (if (> n (count @res))
        (recur)
        @res))))

(time (process 9))

;; "Elapsed time: 1000.639079 msecs"
;; => [8 7 5 6 4 3 2 1 0]
(defn unchangeable-lib-request [n]
  (Thread/sleep 1000)
  n)

(defn process [n]
  (let [c (async/chan 10)]
    (dotimes [i n]
      (async/go
        (async/>! c (unchangeable-lib-request i))))
  (loop [result []]
    (if (> n (count result))
      (recur (conj result (async/<!! c)))
      result))))

(time (process 9))

;; "Elapsed time: 2001.770183 msecs"
;; => [0 4 1 6 7 2 5 3 8]
(defn process [n]
  (let [c (async/chan 10)]
    (dotimes [i n]
      (async/go
        (async/>! c (magic-async-parking-wrapper
                      (unchangeable-lib-request i))))
  (loop [result []]
    (if (> n (count result))
      (recur (conj result (async/<!! c)))
      result))))

(time (process 9))

;; "Elapsed time: 1003.2563 msecs"

有可能吗?

共有1个答案

朱翔
2023-03-14

我建议:

  • 使用futures创建线程,并使用put!将结果从任何go块外部放回核心异步通道,类似于:(future(put!chan(worker-function)))
  • 然后使用go块在该(单个)频道上等待,在获得结果时输入结果。
 类似资料:
  • 如另一个问题中所述,当使用Undertow时,所有处理都应该在专用的工作线程池中完成,如下所示: 我知道可用于显式地告诉Undertow在专用的线程池中调度请求以阻止请求。我们可以通过将包装在实例中来修改上面的示例,如下所示: 调用此方法将exchange置于阻塞模式,并创建一个BlockingHttpExchange对象来存储流。当交换处于阻塞模式时,输入流方法变得可用,除了阻塞和非阻塞模式之间

  • 默认情况下,通道发送和接收数据是阻塞的。然而我们可以使用select的一个default的选项来实现无阻塞发送或接收数据,甚至可以将多个select的case选项和default选项结合起来使用。 package main import "fmt" func main() { messages := make(chan string) signals := make(chan bo

  • 在完美的世界,将没有战争或饥饿,所有 Api 将使用异步写,阳光明媚,绿色的草地有跳来跳去的兔子和手牵手的小羊羔。 但是,现实世界并不是这样。(你看过新闻最近吗?) 事实是,大多数库,特别是在JVM的生态,Y有许多是同步API,许多的方法有可能阻塞。一个很好的例子是JDBC API - 这是本质上的同步,不管如何努力尝试,Vert.x 不能撒上魔法使之同步。 我们不打算在一夜之间把一切改写成异步,

  • 问题内容: 我可以很轻松地在Node.js中编写非阻塞I / O。 这就是整个库的用途。 但是所做的任何计算都是阻塞的。任何通过事件发送器的消息都将被阻止。 例如,发出事件立即得到解决,因此被阻止: 除了将调用包装起来外,如何使代码无阻塞? 我希望在事件循环的每个周期中进行尽可能少的计算,以便可以同时为尽可能多的客户端提供服务。 如何以非阻塞方式编写代码? 当我拥有非阻塞代码时,如何在多个进程之间

  • 问题内容: 根据我在这里所读的内容,golang调度程序将自动确定goroutine是否在I / O上阻塞,并将自动切换为在未阻塞的线程上处理其他goroutine。 我想知道的是调度程序如何确定该goroutine已停止阻止I / O。 它是否只是经常进行某种轮询以检查其是否仍处于阻塞状态?是否运行某种后台线程来检查所有goroutine的状态? 例如,如果要在需要5s的goroutine中执行

  • 问题内容: 我对如何在python / twisted中编写异步代码感到困惑。假设(出于参数考虑)我正在向世界公开一个函数,该函数将接受一个数字,如果它是质数/非质数,则返回True / False,因此它看起来像这样: (只是为了说明)。 现在,假设有一个Web服务器需要根据提交的值调用IsPrime。对于大型服务器,这将需要很长时间。 如果在此期间另一个用户要求小数的素数,是否有一种方法可以使