简体   繁体   English

什么时候阻塞IO块?

[英]When exactly Blocking IO blocks?

InputStream.available() javadoc: InputStream.available() javadoc:

Returns the number of bytes that can be read (or skipped over) from this input stream without blocking返回可以从此输入流读取(或跳过)而不会阻塞的字节数

  1. I think that blocking means that thread from which I called read() is blocked (control flow doesn't go further) until that read() returns.我认为阻塞意味着我调用read()线程被阻塞(控制流不会更进一步),直到read()返回。 In this sense I cannot see any scenario in which read() can be called without blocking.从这个意义上说,我看不到任何可以在不阻塞的情况下调用 read() 的场景。

  2. Another meaning of blocking may be that if I want to read 3 bytes and have none or just 1 byte available, read() would block and wait for more bytes to appear - but I cant't understand it that way b/c then calling read() and trying to read more than available may cause eternal blocking (just imaging reading 100 bytes from a file of 10 bytes).阻塞的另一个含义可能是,如果我想读取 3 个字节并且没有或只有 1 个字节可用,则read()会阻塞并等待更多字节出现 - 但我不能这样理解 b/c 然后调用read()并尝试读取超过可用的内容可能会导致永久阻塞(只是从 10 字节的文件中读取 100 字节的图像)。

In which sense java.io is blocking (1) or (2)?在哪个意义上 java.io 正在阻塞 (1) 或 (2)?

I cannot simulate a situation when read methods of IO block (in sense (2)) with FileInputStream or ByteArrayInputStream:当使用 FileInputStream 或 ByteArrayInputStream 读取 IO 块的方法(在意义上(2))时,我无法模拟这种情况:

        // file content is: 1 2 3       
        FileInputStream myStream = new FileInputStream("d:\\file.txt");
        byte[] b = new byte[100];
        myStream.read(b);
        System.out.println("control reached here?");
        System.out.println(Arrays.toString(b));

Output:输出:

reached here?
[122, 100, 122, 120, 118, 122, 120, 32, 118, 122, 120, 118, 32, 122, 120, 118, 32, 122, 118, 99, 122, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Second call myStream.read(b) would just return -1 also without blocking.第二次调用myStream.read(b)也只会返回 -1 而不会阻塞。

In which scenario does blocking occur?什么场景会发生阻塞?

I thought it occurs if I try to read 5 bytes and there is three.我认为如果我尝试读取 5 个字节并且有 3 个字节,就会发生这种情况。 If there is none it means EOF / end-of-stream and -1 is returned (no blocking either).如果没有,则表示 EOF / 流结束并返回 -1(也没有阻塞)。

PS I tend to think that java.io is both (1) and (2): it is synchronous (1) and blocking (2), but that blocking is really observed only working with sockets ( Socket.getInputStream() / Socket.getOutputStream() ). PS 我倾向于认为java.io 既是 (1) 又是 (2):它是同步的 (1) 和阻塞的 (2),但实际上观察到阻塞仅适用于套接字( Socket.getInputStream() / Socket.getOutputStream() )。

More or less option 2, but you don't have to worry about read blocking even if there's some data to process already.或多或少的选项 2,但即使已经有一些数据要处理,您也不必担心read阻塞。

Here's a tip: Don't use available().这里有一个提示:不要使用 available()。 It's effectively useless, the information it grants does not really let you do things that you otherwise couldn't do.它实际上毫无用处,它提供的信息并不能真正让您做原本无法做的事情。

Let's say you have a TCP network connection.假设您有一个 TCP 网络连接。 Until you or the opposite side hangs up the connection, there is no limit to how many bytes can be sent across the line, but on the flipside, it's possible that there are, say, 10 bytes left to read and no more will be forthcoming for a while because the sender is, for now, silent.在您或对方挂断连接之前,可以通过线路发送的字节数没有限制,但另一方面,可能还有 10 个字节可供读取,并且不会再发送有一段时间,因为发件人目前处于沉默状态。

Let's say you then do this:假设你然后这样做:

byte[] b = new byte[100];
int r = in.read(b);

What's going to happen here, is that r will be 10 , the first 10 slots in your b will be filled, and that's that.这里会发生什么, r将是10b的前 10 个插槽将被填充,就是这样。 read 'smartly' returns: It does NOT return if there are 0 bytes (read guarantees that it'll block until it either reads at least 1 byte, or the stream is closed, in which case it returns -1 )... and if there are bytes to read, it reads an efficient chunk of it. read 'smartly' 返回:如果有 0 个字节,它不会返回(read 保证它会阻塞,直到它读取至少 1 个字节,或者流关闭,在这种情况下它返回-1 )......和如果有字节要读取,它会读取其中的一个有效块。

blocking , specifically, means that the thread will be paused and won't resume until something changes. blocking ,具体来说,意味着线程将被暂停并且在某些事情发生变化之前不会恢复。 (bytes come in, or the stream is closed). (字节进来,或者流被关闭)。

Scenario 2 is the meaning.场景2就是这个意思。

(Updated after some experimentation) (经过一些实验更新)

It seems that local disk file I/O is not considered blocking.似乎本地磁盘文件 I/O 不被视为阻塞。 For a FileInputStream, the available() method returns the remaining length of the file.对于 FileInputStream,available() 方法返回文件的剩余长度。 That is, if the file is 91764 bytes long, and you read 4 bytes, after that available() will return 91760.也就是说,如果文件长度为 91764 字节,并且您读取了 4 个字节,则之后 available() 将返回 91760。

I find that result surprising;我发现这个结果令人惊讶; your thread will surely block for disk I/O if you try to read those 91760 bytes.如果您尝试读取那些 91760 字节,您的线程肯定会阻塞磁盘 I/O。

The result is more understandable for network socket connections.结果对于网络套接字连接更容易理解。 The amount of data that may arrive from the remote system in future is of course unknown;将来可能从远程系统到达的数据量当然是未知的; available() will tell you how much has already arrived and can be read now. available() 会告诉你有多少已经到达并且现在可以读取。 In this case, 'blocking' would be of indefinite duration - waiting until the remote host may send, which is outside the knowledge of the I/O system.在这种情况下,“阻塞”将是无限期的——等待远程主机可以发送,这是 I/O 系统不知道的。 at leaves 20 bytes available for a further read without blocking. at 留下 20 个字节可用于进一步读取而不会阻塞。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM