代码之家  ›  专栏  ›  技术社区  ›  Matthew Rankin val

在屏幕中记录数据时读取Python文件

  •  2
  • Matthew Rankin val  · 技术社区  · 14 年前

    为了从逻辑控制器捕获数据,我使用 screen 作为终端仿真器并通过 KeySpan USA-19HS USB Serial Adapter talk2controller <filename> 哪里 文件名 是数据文件的名称。

    #!/bin/bash
    if [ -z "$1" ]; then
        echo Please provide the filename to save the logfile
        exit
    fi
    LOGFILE=$1
    echo "logfile $1" > screenrc        # Set the logfile filename
    echo "logfile flush 1" >> screenrc  # Wait 1 sec before flushing buffer to filesystem
    screen -L -c screenrc /dev/tty.KeySerial1 19200
    

    screenrc . 然后我用以下命令调用屏幕:

    1. -L 日志记录已启用
    2. -c screenrc 覆盖默认配置文件
    3. /dev/tty.KeySerial1 19200 使用19200的波特率与串行端口通信

    我记录的每个测试大约需要36分钟,包含速度、加速度和位置信息。根据加速度,我就知道测试是有效的。目前,我正在等待测试之后运行Python matplotlib 脚本来绘制速度、加速度和位置,以查看测试是否有效,然后再进行下一个测试。

    问题

    在我看来,在捕获更多数据的同时绘制数据有两种选择:

    • 方案1:
      • 问题1:
    • 方案2: 从使用屏幕切换到使用 pySerial
      • 问题2: 如果我切换到pySerial,我可以运行两个线程来减少代码的绘图部分不影响数据捕获代码的可能性吗?这能给我买点什么吗?

    问题3: 有没有更好的选择,我还没想到?

    3 回复  |  直到 6 年前
        1
  •  3
  •   apenwarr    14 年前

    选项1和2都可以,但是哦,天哪,以一切美好的名义,避免使用线程!你最终会遇到两个世界中最糟糕的:锁定问题, 图形线程中的异常将终止整个程序(包括日志线程)。正如其他人所提到的,使用两个单独的过程来实现这一点是很好的。 screen 对于这个目的来说,工具的选择有点奇怪,就像用python手工编写代码一样。我刚刚把talk2controller脚本重写为以下这个小脚本:

    stty -F /dev/tty.KeySerial1 19200 raw
    cat </dev/tty.KeySerial1 >logfile
    

    (您也可以使用 >>logfile 如果希望脚本的每次运行都附加到文件中,而不是从头开始重写它。)

    答案是:你可以这样做,但你是对的,你不能保证一行字在你读的时候不会写一半。(如果你写下你自己的替代品 cat 屏幕 实际上,您可以通过始终使用 os.read() 而不是 sys.stdout.write() print .)

    然而,无论如何,这种保证是不需要的。你只需要在阅读文件时小心,就不会有问题。从本质上讲,不完整的一行就是不以 \n 换行符。因此:

    for line in open('logfile'):
        if not line.endswith('\n'): break
        ...handle valid line...
    

    自从 \不 字符是日志中每一行最后写的东西,你肯定知道如果你读一个

        2
  •  1
  •   jathanism    14 年前

    我想 方案1 这是完全可行的,因为您可以轻松地将Python“tail”日志文件放在一个只读管道中,这样在运行时就不会对其造成伤害 screen

    如果你很好奇并且想看到一些工作代码,我的一个个人项目就利用了这个功能。这个项目叫做 thrasher-logdrop 而且胆量很大 logdrop.py . 基本流程是:

    • do_tail()
    • tail_lines()
    • handle_line()
        3
  •  1
  •   llasram    14 年前

    fork() socketpair() 或者其他IPC机制;或者(b)将输出文件对象配置为行缓冲——使其在写入每一整行后显式同步——并在第二个进程中监视它的新内容。

    screen 的缓冲行为。您可以监视其日志文件中的新内容,但是您的日志代码需要准备好同时处理不完整的行和大块数据。根据具体的缓冲行为,您甚至可能根本看不到任何数据,直到