char准备就绪时从输入端口块读取

时间:2014-05-21 10:41:05

标签: io scheme racket blocking

我不明白为什么我的代码不起作用。我有一个向量,此向量在某些位置包含input-ports,在其他位置包含0。如果有input port,我想检查是否有可用的数据。如果有可用数据,请阅读并将其排队。如果没有,请继续。

这是我的代码:

;The name of the vector is 'in'.
(define (read-ports)
  (let loop
    ((idx 0))
    (if (not (= idx (vector-length in)))
        (let ((port (vector-ref in idx)))
          (if (not (eq? port 0))
              (if (char-ready? port)
                  (let ((data (read port)))
                    (sendm buffer 'enqueue! data)) ;my own queue
                  (loop (+ idx 1)))
              (loop (+ idx 1))))
        'done)))

我的问题是,char-ready返回true,但read操作仍会阻止!我确定数据正在发送,但为什么它会阻止?我尝试发送的数据为vectors,但这些数据的值介于0和255之间。实际上它们是vectors的{​​{1}}。

提前致谢

1 个答案:

答案 0 :(得分:1)

按要求回答您的问题:

read阻止,直到它可以读取完整的 s表达式。因此,如果您尝试读取向量#(1 2 3 4),则#(1 2部分的字节可以立即读取 - 但不一定是剩余3 4)的字节。


提出一般性建议:

虽然我不知道你想要完成什么的上下文,但听起来你有N input-port个,而你的read-ports函数会尝试从vector读取buffer每个端口,将结果放在某个中心'done,然后返回read-ports。 (我不确定你是否会一次或多次致电thread。)

更好的设计可能将使port读取每个read,并让每个线程通过使用异步通道将其结果放入中央缓冲区保护/协调对该缓冲区的访问。所以你有N个线程,每个线程读取N个端口中的一个。

这样,你不必担心阻塞 - 每个线程调用{{1}},并在完成后完成。 (OTOH这种设计意味着矢量可能无序读出;如果重要,你可以通过几种方式处理它。)

同样,我不知道你的确切目标,但基本上我建议使用其轻量级的绿色线程和频道与“Racket”合作。