要从逻辑控制器捕获数据,我使用screen作为终端仿真器,并通过KeySpan USA-19HS USB Serial Adapter连接我的MacBook。我创建了以下bash脚本,以便我可以键入talk2controller <filename>
,其中 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
我已经更改了日志文件的文件名,并在将日志文件缓冲区刷新到文件系统之前等待,从默认值10秒更改为1秒。我将这些命令保存到screenrc
。然后我用以下方式调用屏幕:
-L
- 已启用日志记录-c screenrc
- 覆盖默认配置文件/dev/tty.KeySerial1 19200
- 使用波特率19200 我记录的每个测试大约需要3-6分钟,包含速度,加速度和位置信息。我知道测试基于加速率是有效的。目前,我等待测试后再运行Python matplotlib脚本来绘制速度,加速度和位置,以确定测试是否有效,然后再进行下一次测试。
为了节省时间,我宁愿在测试中途绘制数据,同时仍在捕获数据。
在我看来,有两种方法可以绘制数据,同时仍然可以捕获更多数据:
问题3:我有没有想过更好的选择?
答案 0 :(得分:3)
选项1和2都可以使用,但是哦,男孩,以所有好事的名义,避免使用线程!你最终会遇到两个世界中最糟糕的事情:锁定问题,和图形线程中的异常无论如何都会杀死整个程序(包括日志记录线程)。正如其他人提到的那样,使用两个单独的过程就可以了。对于这个目的,screen
是一个奇怪的工具选择,就像在python中手动编写代码一样。我只是将talk2controller脚本重写为这个简单的脚本:
stty -F /dev/tty.KeySerial1 19200 raw
cat </dev/tty.KeySerial1 >logfile
(如果您希望每次运行脚本都附加到文件,而不是从头开始重写,也可以使用>>logfile
。)
另一个问题是,只要其他人正在写文件,是否可以从文件中读取程序。这个问题的一个更具体的版本是:如果在您尝试阅读时,日志行是半写的,该怎么办?
答案是:你被允许这样做,但是你是对的,你不能保证在你阅读它时不会写一行。 (如果您为cat
或screen
编写了自己的替代品,您实际上可以通过始终使用os.read()
而非sys.stdout.write()
或print
写入文件来实现此保证。 。)
但是,无论如何都不需要这种保证。您只需要在阅读文件时要小心,否则您将永远不会遇到问题。从本质上讲,不完整的行只是一个不以\n
换行符结尾的行。因此:
for line in open('logfile'):
if not line.endswith('\n'): break
...handle valid line...
由于\n
字符是日志的每一行写的最后一个字符,因此您肯定知道如果您读取\n
字符,那么它之前的所有内容都是正确写入的。
答案 1 :(得分:1)
我认为选项1 是完全可行的,因为您可以轻松地将Python“尾随”日志文件放在只读管道中,以便在screen
仍然存在时不会对其造成任何伤害写给它。在拖尾文件时,只要在日志文件中检测到新的日志事件,就可以执行指定的操作。
如果您很好奇并希望看到一些正常工作的代码,我的个人项目会利用此功能。该项目名为thrasher-logdrop,胆量为logdrop.py。基本流程是:
do_tail()
tail_lines()
handle_line()
答案 2 :(得分:1)
我说选项2是要走的路。当您收到输入时,您可以完全控制对输入的每个字节执行的操作。您可以拥有一个非常简单的Python脚本,它只是在读取数据时将数据写入磁盘。您的绘图代码可以在fork()
第一个创建的完全独立的流程中运行。要从一个到另一个获取数据,您可以(a)让第一个进程也写入socketpair()
或其他IPC机制;或者(b)将输出文件对象配置为行缓冲 - 使其在每写完整行后显式同步 - 并在第二个进程中监视它以获取新内容。
选项1的问题在于您无法控制screen
的缓冲行为。您可以监视其日志文件以获取新内容,但您的日志记录代码需要准备好同时处理不完整的行和大块数据。根据确切的缓冲行为,在screen
进程退出之前,您甚至可能根本看不到任何数据!