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

Io char就绪时从输入端口块读取,io,scheme,racket,blocking,Io,Scheme,Racket,Blocking,我不明白为什么我的代码不起作用。我有一个向量,这个向量在某些位置包含输入端口,在其他位置包含0。当有输入端口时,我想检查是否有可用数据。如果有可用数据,请读取数据并将其排队。如果没有,继续前进 这是我的密码: ;The name of the vector is 'in'. (define (read-ports) (let loop ((idx 0)) (if (not (= idx (vector-length in))) (let ((port (vec

我不明白为什么我的代码不起作用。我有一个向量,这个向量在某些位置包含
输入端口
,在其他位置包含
0
。当有
输入端口时,我想检查是否有可用数据。如果有可用数据,请读取数据并将其排队。如果没有,继续前进

这是我的密码:

;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)))
我的问题是,
charready
返回
true
,但是
read
操作仍然阻塞!我确定数据正在发送,但为什么会被阻止?我试图发送的数据是
向量
,但它们包含0到255之间的值。所以实际上它们是
字节的
向量


提前感谢您回答以下问题:

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


提出一般性建议:

虽然我不知道您想要完成什么,但听起来您有N个
输入端口
s,您的
读取端口
函数将尝试从每个端口读取一个
向量
,将结果放入某个中央
缓冲区
,然后返回
'done
。(我不确定您是否会调用
读取端口一次或多次。)

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

这样,您就不必担心阻塞问题——每个线程都调用
read
,并且在完成时就完成了。(这种设计意味着向量可能会被无序读取;如果这很重要,你可以用几种方法来处理。)


同样,我不知道您的确切目标,但基本上我建议您使用Racket的轻量级绿色线程和通道来“使用”它。

char ready?
如果您可以使用
read byte
,则是正确的,不是
read
。是否有什么东西可以用来检查
read
是否将被阻止?是否确实需要
read
?我将研究
读取字节-*
peek-*
过程。此外,您还可以使用
循环或每个
使用
大大简化代码。我正在发送
向量。但它们包含0到255之间的值,因此本质上是
字节。我可以用
readbytes
读取这些字节向量吗?或者我必须将它们转换为其他内容吗?我正在使用线程来执行此操作,但我需要从代码中删除它们。