通过数据库在python进程之间交换数据

时间:2019-02-22 23:34:08

标签: python postgresql raspberry-pi multiprocessing data-acquisition

我有一个带有MCC118 daqhat的树莓派。目标是三个方面:

  1. 获取数据并将其记录到数据库
  2. 通过专用LAN将数据流尽可能接近实时地传输到浏览器(网络GET / POST速度受限制)
  3. 分析此数据并根据分析结果激活设备(RPi.GPIO)

我的程序同时受cpu和I / O约束,因为该程序必须等待从daqhat输入的数据(受I / O约束),并且一旦读取数据,就必须对其进行记录和分析(受cpu约束)。对于cpu绑定部分,我正在利用多处理程序来建立数据库。然后通过查询数据库来更新浏览器显示(通过烧瓶)。为了有效地做到这一点,我开发了以下示例代码,作为记录和显示项目的基础:

#!/usr/bin/env python
#  -*- coding: utf-8 -*-

import sys
import random
import psycopg2 as sql
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
from multiprocessing import Process

def fill_table():
    conn_fill = sql.connect('dbname=mp_example user=pi')
    cf = conn_fill.cursor()
    while True:
        cf.execute('INSERT INTO ran_num (ran) VALUES (%s);', (random.random(),))
        conn_fill.commit()

def read_table():
    conn_read = sql.connect('dbname=mp_example user=pi')
    cr = conn_read.cursor()
    while True:
        cr.execute('SELECT * FROM ran_num WHERE id=(SELECT MAX(id) FROM ran_num);')
        val = cr.fetchone()
        if val:
            print('\r' + str(val[0]) + ' - ' + str(round(float(val[1]), 3)), end='')
        sys.stdout.flush()
    print('\n')

def main():
    conn_main = sql.connect('dbname=mp_example user=pi')
    cm = conn_main.cursor()
    cm.execute('DROP TABLE IF EXISTS ran_num;')
    cm.execute('CREATE TABLE ran_num (id SERIAL PRIMARY KEY, ran VARCHAR);')
    conn_main.commit()
    cm.close()
    conn_main.close()
    print('Starting program, press CTRL + C to quit... \n')

if __name__ == '__main__':
    main()
    try:
        p1 = Process(target=fill_table)
        p1.start()
        p2 = Process(target=read_table)
        p2.start()
    except KeyboardInterrupt:
        p1.join()
        p2.join()
        print('Processes have closed without zombies...\n')

我刚刚向自己介绍了Postgres(我正在使用sqlite3),目的是为了以我认为是“数据安全”的方式来做事并发编写和查询数据并发。但是,我的问题如下:

  1. 是否有更有效的内存使用和/或数据安全的方法(例如管道)?
  2. 抛出KeyboardInterrupt异常时是否有更好的退出方法? (我的异常打印语句从不打印,表明进程也离开了进程僵尸。)

注意:最初,每次通过LAN发出GET请求时,我只是从daqhat读取单个数据值,但是,这意味着采样率取决于网络速度。为了保证数据的完整性和一致性,我想使用多处理功能以恒定的采样率进行数据采集,并根据网络请求从数据库中读取数据。

0 个答案:

没有答案