Python sys.stdin.read(max)阻塞直到读取最大值(如果max> = 0),阻塞直到EOF为止,但是select表示有待读取的数据 [英] Python sys.stdin.read(max) blocks until max is read (if max>=0), blocks until EOF else, but select indicates there is data to be read

查看:73
本文介绍了Python sys.stdin.read(max)阻塞直到读取最大值(如果max> = 0),阻塞直到EOF为止,但是select表示有待读取的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是:

select表示有要读取的数据,我想读取其中的任何内容,我不想等待出现max数量.如果max< = 0,则读取将一直等待直到遇到EOF;如果> 0读取将阻塞,直到可以读取max个字节为止.

select indicates that there is data to be read, I want to read whatever is there, I do not want to wait for a max amount to be present. if max <= 0 then read waits until EOF is encountered, if max>0 read blocks until max bytes can be read.

我不想要这个,我想阅读选择放入准备阅读"列表中的所有内容. read(1)不切实际,因为这将涉及大量的read调用.但是它一定不能阻塞.

I don't want this, I want to read whatever amount made select put it in the "ready for reading" list. read(1) isn't practical because this will involve A LOT of calls to read. BUT it mustn't block.

是否有一种方法可以在select返回时找出缓冲区中存在的数量(如果返回则表明可以读取某些内容,而不是超时)并读取该数量?有没有一种方法可以像使用套接字那样使用max?

Is there a way to find out the amount present in the buffer when select returns (if it returns indicating something can be read, rather than timed out) and read that amount? Is there a way to use max as one would with sockets? Where it reads as much as it can instantly, then returns?

一个解决方案可能是将文件置于非阻止模式下进行读取?我不确定,我没想到这种直到EOF"行为.

A solution might be to put the file in non-blocking mode for the read? I'm not sure, I didn't expect this "until EOF" behavior.

我会继续阅读和尝试,但我只花了30分钟左右,就没有走近,这就是为什么我吸引您.

I will keep reading and trying but I've just spent 30 minutes or so and gotten no closer, that's why I appeal to you.

注意

有很多问题询问如何使recv等待大量输入,并使事情阻塞直到最大输入量出现,我正在寻找它.我的问题是阻止了.

There are a lot of questions asking how to make recv wait for an amount of input, and making things block until that max has arrived, I am not looking for this. My problem is it is blocking.

附录

setblocking(False)无法正常工作,我现在正在阅读如何在读取过程中使其不阻塞.文档给了我希望:

setblocking(False) didn't work, I'm now reading on how to make it non-blocking for the duration of the read. I am given hope by the documentation:

stdin.read Found at: sys
read([size]) -> read at most size bytes, returned as a string.

If the size argument is negative or omitted, read until EOF is reached.
Notice that when in non-blocking mode, less data than what was 
 requested
may be returned, even if no size parameter was given.

附录II

似乎read(0)实际上读为0,什么也没有,这导致了一个无限循环,这很有趣!

It seems read(0) actually reads 0, that is nothing, this results in an endless loop, which is interesting!

对不起,我似乎实际上并没有尝试0,我从4096开始(认为它将读取其中的任何内容....)尝试了无参数,但没有设置0.

I'm sorry I didn't actually try 0 it seems, I started with 4096 (thinking it'll read whatever is there....) tried with no parameter, but not with 0.

我想知道read(0)有什么用吗?

I wonder what use read(0) would be?

附录III

我现在在选择方面遇到了问题(我尝试采用read(1)作为解决方案) 这是实际的代码:

I'm now having problems with select (I've tried to take read(1) as a solution) Here's the actual code:

def getInput(self):
    log.log(log.INFO,"GetInput","Select")
    readsReady = select.select((sys.stdin,),(),(),1)[0]
    if len(readsReady) == 0:
        #timed out
        log.log(log.INFO,"GetInput","Select timed out")
        if not self.toClose:
            self.handler.post("GetInput")
        else:
            threads.getCurrentThread().removeAllHandlers()
    else:
        #OPTIMISED FOR READING 1
        #log.log(log.INFO,"GetInput","Reading")
        data = sys.stdin.read(1)
        log.log(log.INFO,"GetInput","Read: "+data)

        if data == "\n":
            self.onInputHandler.post("OnInput",self.buffer)
            self.buffer=""
        else:
            self.buffer+=data
        self.handler.post("GetInput")

以下输出中与此无关的东西很少,它们是"Hello world!".几乎马上就可以通过,然后进行测试!"大约5秒钟 "hello"是我输入的内容,"k"是我稍后输入的内容,输入完两次后,按一次Enter键.

There are few things in the following output unrelated to this, they are the "Hello world!" that comes through almost instantly, and the "TEST!" about 5 seconds in. The "hello" is something I typed, input, the "k" is something I typed later, after typing both I press enter once.

输出:

0.0147    Verbose        1   SocketReader                        Created reader
0.0156    Verbose        2   SocketWriter                        Created writer
0.0260    Information    0   SocketReadWriter                    Created and ready for: ('localhost', 8294)
0.0268    Information    3   GetInput                            Select
Hello World!
1.0281    Information    3   GetInput                            Select timed out
1.0584    Information    3   GetInput                            Select
2.0593    Information    3   GetInput                            Select timed out
2.0896    Information    3   GetInput                            Select
3.0900    Information    3   GetInput                            Select timed out
3.1203    Information    3   GetInput                            Select
4.1215    Information    3   GetInput                            Select timed out
4.1519    Information    3   GetInput                            Select
TEST!
5.1524    Information    3   GetInput                            Select timed out
5.1828    Information    3   GetInput                            Select
hello
6.1467    Information    3   GetInput                            Read: h
6.1770    Information    3   GetInput                            Select
7.1782    Information    3   GetInput                            Select timed out
7.2086    Information    3   GetInput                            Select
8.2098    Information    3   GetInput                            Select timed out
8.2401    Information    3   GetInput                            Select
9.2414    Information    3   GetInput                            Select timed out
9.2717    Information    3   GetInput                            Select
10.2723   Information    3   GetInput                            Select timed out
10.3026   Information    3   GetInput                            Select
k
10.7939   Information    3   GetInput                            Read: e
10.8243   Information    3   GetInput                            Select
10.8245   Information    3   GetInput                            Read: l
10.8547   Information    3   GetInput                            Select
10.8549   Information    3   GetInput                            Read: l
10.8851   Information    3   GetInput                            Select
10.8853   Information    3   GetInput                            Read: o
10.9155   Information    3   GetInput                            Select
10.9157   Information    3   GetInput                            Read: 

10.9459   Information    3   GetInput                            Select
10.9461   Information    3   GetInput                            Read: k
10.9763   Information    3   GetInput                            Select
You said: hello
11.9775   Information    3   GetInput                            Select timed out
12.0123   Information    3   GetInput                            Select
13.0133   Information    3   GetInput                            Select timed out
13.0437   Information    3   GetInput                            Select
^C13.3985   Verbose        2   Threads                             Thread: 2 has ended
14.0442   Information    3   GetInput                            Select timed out
14.0746   Information    3   GetInput                            Select
14.3622   Verbose        1   Threads                             Thread: 1 has ended
15.0758   Information    3   GetInput                            Select timed out
15.1363   Information    3   GetInput                            Select
16.1373   Information    3   GetInput                            Select timed out
16.1677   Verbose        3   Threads                             Thread: 3 has ended

在这里更容易看到: http://pastebin.com/raw.php?i = H6UHHmy8

奇怪的是什么?

它读取hello的"h",但直到k出现时才读取"hello \ n",如果可以的话,它总是在后面1个换行符之前的1个字母.

It reads the "h" of hello, but doesn't read the "hello\n" until k happens, it is always 1 letter ahead of 1 newline behind if that makes sense.

选择多个电话会引起问题吗? (在套接字读取器还使用select的另一个线程中)

Would multiple calls to select cause a problem? (in another thread the socket reader also uses select)

日志的格式为:

*程序启动后的时间

*日志级别

*线程ID(正在运行的线程之间是唯一的)

*Thread ID (Unique among running threads)

*日志标签

*日志消息

Handler类的作用

允许线程安全地相互发送消息,处理程序检查队列(并且在某个时间发生的任何预定事件,例如TEST,发生在不同线程上的都不必担心), "GetInput"安排另一个对GetInput的调用,将其放在队列的后面. "OnInput"消息传递给另一个线程的处理程序,我想处理该线程的输入.

is allow threads to post messages safely to each other, the handler checks a queue (and any booked events to happen at a certain time, like the TEST, which happens on a different thread don't worry), the post of "GetInput" scheduals another call to GetInput, putting it at the back of the queue. The "OnInput" message is passed to the handler of a different thread, the one I want to deal with input.

我这样做是因为它提供了一种处理线程的好方法,并且意味着我有很好的可重用代码(如SocketReadWriter),我希望这不会导致对线程模型的批评,但是它实际上有效.问题出在我试图获取用户输入的问题上.

I've done it this way because it provides a nice way to handle threading, and means I have nice re-usable code (like the SocketReadWriter), I hope this doesn't result in criticism of my threading model, but it actually works. The problem is with my attempt to get user input.

您还可以看到当我执行ctrl + c时该设备关闭,这就是toClose的功能.当select超时时,如果应该关闭,它将关闭.线程在没有处理程序时结束(处理程序仅在运行线程的函数返回后才接管,该函数可能会创建一个为成员提供处理程序的类,因此当构造函数返回时,该函数将返回,有一个使类保持活动状态的处理程序)

You can also see when I do ctrl+c that the thing shuts down, this is what the toClose thing does. When select times out, if it is supposed to close, it will. A thread is ended when it has no handlers left (handlers only take over after the function the thread is to run has returned, this function might create a class which has a handler for a member, thus when the constructor returns, and the function returns, there's a handler keeping the class alive)

变通

def getInput(self):
    log.log(log.INFO,"GetInput","Select")
    if sys.stdin.closed:
        readsReady = []
    else:
        readsReady = select.select((sys.stdin,),(),(),1)[0]
    if len(readsReady) == 0:
        #timed out
        log.log(log.INFO,"GetInput","Select timed out")
        if not self.toClose:
            self.handler.post("GetInput")
        else:
            threads.getCurrentThread().removeAllHandlers()
    else:
        data = sys.stdin.readline()
        if len(data) == 0:
            log.log(log.WARN,"GetInput","No data was returned indicating the file was closed")
            self.handler.post("GetInput") #if this is a close event, the next
            #timeout will deal with it
            return
        if data[-1] == "\n":
            data = data[:-1]
        log.log(log.INFO,"GetInput","Read: "+data)
        self.onInputHandler.post("OnInput",data)
        #if data == "\n":
        #   self.onInputHandler.post("OnInput",self.buffer)
        #   self.buffer=""
        #else:
        #   self.buffer+=data
        self.handler.post("GetInput")

def onClose(self):
    #log.log(log.WARN,"Input: OnClose","Called")
    self.toClose = True
    sys.stdin.close()

推荐答案

os模块中,有

In os module there is os.read function that allows lower level control over reading from file descriptor. It is nonblocking as long as there is at least a byte ready to read.

os.read(fd, n)

从文件描述符fd读取最多n个字节.返回一个包含读取的字节的字符串.如果文件末尾被fd引用 已达到,将返回一个空字符串.

Read at most n bytes from file descriptor fd. Return a string containing the bytes read. If the end of the file referred to by fd has been reached, an empty string is returned.

可用性:Unix,Windows.

Availability: Unix, Windows.

注意:此函数用于低级I/O,并且必须应用于os.open()pipe()返回的文件描述符.要读取内置函数open()popen()fdopen()sys.stdin返回的文件对象",请使用其read()readline()方法.

Note: This function is intended for low-level I/O and must be applied to a file descriptor as returned by os.open() or pipe(). To read a "file object" returned by the built-in function open() or by popen() or fdopen(), or sys.stdin, use its read() or readline() methods.

这篇关于Python sys.stdin.read(max)阻塞直到读取最大值(如果max&gt; = 0),阻塞直到EOF为止,但是select表示有待读取的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆