在一个时间间隔内读取标准输出

问题描述

背景

我正在使用 tcpdump 来监视数据包。我在 60 秒内遍历实时和汇总数据中的每一行。

然后,在 60 秒后,我更新了数据库。我需要每 60 秒不断有数据,即使没有数据包(通过插入空数据)。

问题

如果没有互联网或数据包,循环不会继续,我必须等待 x 秒才能下一次输出。问题是间隔可以> 60s。

当前代码

ts = int(time.time())

p = subprocess.Popen(
    (
        "tcpdump","-neqli","eth0"
    ),stdout=subprocess.PIPE,stderr=subprocess.PIPE,universal_newlines=True,)

interval = 60
sessions = {}

for row in iter(p.stdout.readline,""):
    # Do some work,aggregate data
    splited_row = row.split(" ")
    log_ts = splited_row[0]
    sessions[log_ts] = "Anything"
    if int(time.time()) - interval > ts:
        # Insert in database
        insert_in_database(sessions)
    ts = int(time.time())

解决方

感谢@Gerd,我不得不使用线程和队列。

在生产者中,我使用上面没有时间部分的代码。首先,我获取当前队列数据以在每个新输入时更新它。然后我将聚合数据放入其中,而不是插入。

然后,我的消费者每 60 秒循环一次,获取队列数据并插入。

解决方法

我建议使用带有两个线程的生产者-消费者方法:Here is a complete example(使用随机整数值而不是字符串)。

在您的情况下,生产者线程将从子进程读取 tcpdump 输出并将结果放入队列中,消费者线程将每 60 秒查看一次队列并找到一些数据或队列是空的。所以你的消费者线程主循环看起来像这样:

while True:
    if not q.empty():
        item = q.get()
        print('Getting ' + str(item) + ' : ' + str(q.qsize()) + ' items in queue')
        # insert data into database
    else:
        print('No data')
        # insert null data into database
    time.sleep(60.0)