Peak将允许我们在最小化阻塞时间的同时执行查找和求值。为什么子流程而不是纯python ping实现subprocess.Popen.stdout.peek()-你有参考资料吗(我在文档中找不到)?@sKwa这里有一个指向peek上文档的链接——在类io
Peak将允许我们在最小化阻塞时间的同时执行查找和求值。为什么子流程而不是纯python ping实现subprocess.Popen.stdout.peek()-你有参考资料吗(我在文档中找不到)?@sKwa这里有一个指向peek上文档的链接——在类io,python,subprocess,peek,Python,Subprocess,Peek,Peak将允许我们在最小化阻塞时间的同时执行查找和求值。为什么子流程而不是纯python ping实现subprocess.Popen.stdout.peek()-你有参考资料吗(我在文档中找不到)?@sKwa这里有一个指向peek上文档的链接——在类io.BufferedReader下。peek()是BufferedReader的属性,self.ping.stdout是它的一个实例。BufferedReader是基本python io模块中的一个类。@sKwa原则上,我倾向于避免使用本机模块,
Peak将允许我们在最小化阻塞时间的同时执行查找和求值。为什么
子流程
而不是纯python ping实现subprocess.Popen.stdout.peek()
-你有参考资料吗(我在文档中找不到)?@sKwa这里有一个指向peek上文档的链接——在类io.BufferedReader下。peek()是BufferedReader的属性,self.ping.stdout是它的一个实例。BufferedReader是基本python io模块中的一个类。@sKwa原则上,我倾向于避免使用本机模块,尤其是那些进行系统调用并且可能需要根访问的模块。在这个特定的例子中,我想创建一个无依赖性的程序。为什么子进程
而不是纯python ping实现subprocess.Popen.stdout.peek()
-你有参考资料吗(我在文档中找不到)?@sKwa这里有一个指向peek上文档的链接——在类io.BufferedReader下。peek()是BufferedReader的属性,self.ping.stdout是它的一个实例。BufferedReader是基本python io模块中的一个类。@sKwa原则上,我倾向于避免使用本机模块,尤其是那些进行系统调用并且可能需要根访问的模块。在这个特定的例子中,我想制作一个无依赖性的程序。我相信只有当文件关闭时,这个程序才有效。如果子流程仍在进行中,readline()
将阻塞,直到读取完整行。另外,我没有将任何外部输入传递给Popen,因此,不管它值多少钱,我发现比起运行一个进行系统调用的模块,它更可取。阻塞是一个问题吗?如果是这样,您将需要缓冲读取(我将添加一个示例)。其余的都是建议,具体取决于您的用例:)对于非阻塞阅读,建议阅读此线程:@sKwa这两种方法有什么不同?AFAICS都使用辅助线程,唯一的区别是队列与列表。在这种情况下,为什么排队更好?@ShmulikA不必太费劲,我只是提出要读一个线程,没有别的了。)我相信只有在文件关闭的情况下,这才有效。如果子流程仍在进行中,readline()
将阻塞,直到读取完整行。另外,我没有将任何外部输入传递给Popen,因此,不管它值多少钱,我发现比起运行一个进行系统调用的模块,它更可取。阻塞是一个问题吗?如果是这样,您将需要缓冲读取(我将添加一个示例)。其余的都是建议,具体取决于您的用例:)对于非阻塞阅读,建议阅读此线程:@sKwa这两种方法有什么不同?AFAICS都使用辅助线程,唯一的区别是队列与列表。在这种情况下,为什么排队更好?@ShmulikA不必太费劲,我只是想读一个线程,仅此而已。)据我所知,peek()
的输出只有在读过流的最后一次窥视时才会刷新,这意味着它对于实际检查是否有新数据没有用处——而且我也找不到一个好的方法。值得一提的是,如果我延迟第一次调用直到积累了大量数据,它将返回一个非常长的值。只要调用readline()
就会被阻塞,直到读取换行符为止,这在GUI程序中是不可取的,我想避免运行线程。据我所知,peek()
的输出只有在流被读取超过上次查看的位置时才会刷新,这意味着它对于实际检查是否有新数据没有用处——而且我也找不到一个好的方法。值得一提的是,如果我延迟第一次调用直到积累了大量数据,它将返回一个非常长的值。只要调用readline()
就会阻塞,直到读取换行符为止,这在GUI程序中是不可取的,我希望避免运行线程。
from subprocess import Popen, PIPE, STDOUT
curdir = Popen(['pwd'], stdout=PIPE, stderr=STDOUT)
print(curdir.stdout.readline())
print(curdir.stdout.readline())
print(curdir.stdout.readline())
b'/home/shmulik\n'
b''
b''
def get_next_ping(self):
line = self.ping.stdout.readline()
if not line:
return
line = line.decode('utf-8', 'ignore')
print(line) # Debug statement
try:
return int(float(re.search(r'([0-9.]+)[^m]?ms', line).group(1)))
except (IndexError, AttributeError):
return -1
class Ping(object):
def __init__(self):
if platform == "win32":
command = shlex.split("ping -w 999 -t 8.8.8.8")
elif platform == "linux" or platform == "osx":
command = shlex.split("ping -W 1 8.8.8.8")
self.ping = Popen(command, stdout=PIPE, stderr=STDOUT, shell=True)
self.ping.stdout.readline()
self.ping.stdout.readline()
self.lines = [] # lines will be added here by the background thread
self.lines_lock = Lock() # avoid race conditions on .pop()
self.lines_reader_thread = Thread(target=self._readlines) # start the background thread
self.lines_reader_thread.daemon = True
self.lines_reader_thread.start()
def _readlines(self):
line = None
while line or line is None:
line = self.ping.stdout.readline().decode()
with self.lines_lock:
self.lines.append(line)
def get_next_ping(self):
with self.lines_lock:
if not self.lines:
return
line = self.lines.pop()
print(line) # Debug statement
try:
return int(float(re.search(r'([0-9.]+)[^m]?ms', line).group(1)))
except (IndexError, AttributeError):
return -1
if not has_line:
print(self.ping.stdout.peek()) # Debug statement
self.ping.stdout.readline() # Should refresh the filebuffer.
return None