Python系统标准读取(max)阻塞直到读取max(如果max>=0),blocks直到EOF else,但是选择表示有要读取的数据

2024-04-23 18:28:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我的问题是:

select表示有要读取的数据,我想读取其中的任何内容,我不想等待max数量出现。如果max<;=0,则read等待直到遇到EOF;如果max>;0个读块,直到可以读取max字节。在

我不想要这个,我要读任何数量的选择把它放在“准备阅读”列表中。read(1)是不实用的,因为这将涉及到大量的read调用。但它不能阻挡。在

当select返回时(如果它返回表示可以读取某些内容,而不是超时)并读取该数量时,有没有一种方法可以找出缓冲区中存在的量?有没有一种方法可以像使用套接字一样使用max?在那里它可以立即读取尽可能多的内容,然后返回?在

一个解决方案可能是将文件置于非阻塞模式以进行读取?我不确定,我没想到会有这种“直到EOF”的行为。在

我会继续阅读和尝试,但我只花了30分钟左右,没有接近,这就是为什么我呼吁你。在

注意

有很多问题在问如何让recv等待一个输入量,并使事情阻塞,直到最大值到达,我不是在寻找这个。我的问题是阻塞。在

附录

setblocking(False)不起作用,我现在正在阅读如何使其在读取期间不阻塞。文件给了我希望:

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.

附录二

看起来读(0)实际上读0,那没什么,这导致了一个无休止的循环,这很有趣!在

很抱歉,我没有尝试过0,我从4096开始(认为它会读取任何存在的内容…)尝试了没有参数,但没有使用0。在

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

附录三

我现在在select上遇到问题(我试图将read(1)作为解决方案) 以下是实际代码:

^{pr2}$

下面的输出中很少有与此无关的东西,它们是“Hello world!”这几乎立刻就通过了,“测试!”大约5秒后。 “hello”是我输入的内容,输入,“k”是我稍后输入的内容,输入完两个后,我按enter键一次。在

输出:

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个字母。在

多次调用select会导致问题吗?(在另一个线程中,套接字读取器也使用select)

日志的格式为:

*程序启动后的时间

*日志级别

*线程ID(在运行的线程中唯一)

*日志标记

*日志消息

处理程序类的作用

是允许线程之间安全地传递消息,处理程序检查队列(以及在某个时间发生的任何预定事件,例如在不同线程上发生的测试,不用担心),“GetInput”的发布会安排对GetInput的另一个调用,将其放在队列的后面。“OnInput”消息被传递到另一个线程的处理程序,即我要处理输入的那个线程的处理程序。在

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

你也可以看到当我按ctrl+c键的时候,这个东西会关闭,这就是toClose的功能。当select超时时,如果它应该关闭,它将关闭。一个线程在没有处理程序时结束(处理程序只有在线程要运行的函数返回后才接管它,这个函数可能是c创建一个具有成员处理程序的类,因此当构造函数返回,函数返回时,有一个处理程序使类保持活动状态)

解决方法

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()

Tags: selflog处理程序内容readdataifinformation
1条回答
网友
1楼 · 发布于 2024-04-23 18:28:17

os模块中有一个^{}函数,它允许对从文件描述符的读取进行较低级别的控制。它是非阻塞的,只要至少有一个字节可以读取。在

os.read(fd, n)

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.

Availability: Unix, Windows.

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.

相关问题 更多 >