我正在解析持续更新的日志文件的最后一行。如果匹配,我想将匹配返回到列表并使用该数据启动另一个功能。即使新功能继续运行,我也需要继续监视新条目并解析它们。
我已经从几个不同的角度研究了大约一个星期,并取得了不同的成功。我尝试使用线程,但是遇到获取返回值的问题,我尝试使用全局变量,但无法使其正常工作。我现在正在尝试asyncio,但是要使它正常工作还有更多问题。
def tail():
global match_list
f.seek(0, os.SEEK_END)
while True:
line = f.readline()
if not line:
time.sleep(0.1)
continue
yield line
def thread():
while True:
tail()
def somefun(list):
global match_list
#do things here
pass
def main():
match_list = []
f = open(r'file.txt')
thread=threading.Thread(target=thread, args=(f,))
thread.start()
while True:
if len(match_list) >= 1:
somefun(match_list)
if __name__ == '__main__':
main()
从内存中写入以上内容。 我希望tail()将行返回到somefun()可以使用的列表。 我在使它无法正常工作时遇到问题,我将使用线程或asyncio ..使其在此刻运行。
答案 0 :(得分:0)
在异步中,您可能会使用两个协程,一个协程从文件读取,另一个协程处理文件。由于它们使用队列进行通信,因此不需要全局变量。例如:
import os, asyncio
async def tail(f, queue):
f.seek(0, os.SEEK_END)
while True:
line = f.readline()
if not line:
await asyncio.sleep(0.1)
continue
await queue.put(line)
async def consume(queue):
lines = []
while True:
next_line = await queue.get()
lines.append(next_line)
# it is not clear if you want somefun to receive the next
# line or *all* lines, but it's easy to do either
somefun(next_line)
def somefun(line):
# do something with line
print(f'line: {line!r}')
async def main():
queue = asyncio.Queue()
with open('file.txt') as f:
await asyncio.gather(tail(f, queue), consume(queue))
if __name__ == '__main__':
asyncio.run(main())
# or, on Python older than 3.7:
#asyncio.get_event_loop().run_until_complete(main())
基于异步的解决方案的优点在于,您可以轻松地并行启动任意数量的此类协程(例如,您可以在外部协程中启动gather(main1(), main2())
并运行它们),并将它们共享相同的线程。
答案 1 :(得分:-1)
通过一些小修复,您几乎可以运行此:)(内部评论)
match_list # should be at the module scope
def tail():
# f = open(...) ???
f.seek(0, os.SEEK_END)
while True:
line = f.readline()
if not line:
time.sleep(0.1)
continue
yield line
def thread():
for line in tail():
match_list.append(line) # append line
print("thread DONE!")
def somefun(list):
#do things here
while match_list:
line = match_list.pop(0)
print(line)
def main():
match_list = []
f = open(r'file.txt')
thread=threading.Thread(target=thread, args=(f,))
thread.start()
while True:
if match_list:
somefun(match_list)
time.sleep(0.1) # <-- don't burn the CPU :)