首页 > 解决方案 > 在多个通道上同步/选择-evt(在运行时确定的数量)

问题描述

我正在尝试创建一个非常简单的程序,旨在测量跨多个通道选择和同步所需的时间。本质上,这个概念只是我有一个发送者和一个接收者。在多次迭代中,发送者随机选择两个已提供的通道之一,并在该通道上发送消息。作为其中的一部分,我需要能够控制所涉及的通道数量作为程序的命令行参数,因此我无法将预定数量的通道硬编码到程序中。问题是,我不知道如何从同步模块中获取syncchoice-evt同步模块中获取多个通道。

整个程序(正如我目前拥有的那样)如下:

#lang racket

(provide main)
(require racket/random)

(define (sender iterations channels)
  (match iterations
    [0 (displayln "sender completed")]
    [iter 
           (let ([choice-chan (random-ref channels)])
             (channel-put choice-chan iter)
             (sender (- iter 1) channels))]))

(define (receiver iterations channels notification-semaphore)
  (match iterations
    [0 (begin
         (displayln "receiver completed")
         (semaphore-post notification-semaphore))]
    [iter
     (let ([ignored-choice (sync (choice-evt (vector->values channels)))])
        (begin (displayln ignored-choice)
        (receiver (- iter 1) channels notification-semaphore)))]))

(define (experiment iterations num-channels)
  (let ([channels
         (vector->immutable-vector
          (build-vector num-channels (λ (i) (make-channel))))]
        [notification-semaphore (make-semaphore)])
    (thread (λ () (receiver iterations channels notification-semaphore)))
    (thread (λ () (sender iterations channels)))
    (semaphore-wait notification-semaphore)))

(define (main iterations num-channels)
  (experiment (string->number iterations) (string->number num-channels))
  (displayln "SelectTime completed successfully"))

这些displayln表达式并不是绝对必要的,它们只是在那里,以便我可以看到确实有一些东西从发送者传递到接收者。

我遇到的问题是,当我只使用一个频道时,一切似乎都很好。但是,对于两个或更多通道,我收到一个运行时错误,抱怨数量不匹配 - 预期值为 1,但提供了 2(如果我在命令行上指定更多,则提供更多)。据我所知,这个错误发生在receiver函数内部(choice-evt (vector->values channels)),在处理内部表达式之后,在求值时发生。我已经尝试了所有我能想到的变体,例如channels直接使用不带vector->values; 将向量更改为列表;放弃choice-evt(特别是因为如果我正确阅读了文档,那对于我的测试实际上并不是必需的);将sync发生的地方移出let.

当运行时不知道通道数时,如何通过多个通道同步?看起来使用向量或列表不是解决这个问题的正确方法,但我对什么正确的方法有点困惑。

PS如果您认为这可能有帮助,请在回答时随时以其他方式批评该程序:)

标签: racket

解决方案


您可以使用从可变长度的频道列表apply中创建一个。例如,在上面的代码中,将调用更改为以下内容:choice-evtsync

(sync (apply choice-evt (vector->list channels)))

推荐阅读