2017-01-23 37 views
1

我试图通过Java程序来协调对树莓派Python脚本。我有一些内置无限循环的Python代码,用于读取超声波传感器的距离并将其输出到控制台。 Java代码将其称为shell进程,然后读取OutputStream进程。我遇到的问题是数据大批量到达。相反,我的每一个获得的Python脚本输出到控制台时间的新值,我得到每隔10秒左右的新数据。这是有问题的,因为我试图近乎实时地在Web仪表板上显示数据。读通过一个shell脚本生成发生在批次

该图将如下所示:

DistanceController 
    |--getDistance(public) 
    |--getBufferSize(public) 
    |--buffer(private) 
    |--DistanceThread(private) 
      |--bufferReference (private) 
      |--PythonScriptProcess 

的Java代码如下:

这是一个包装类,实例化新的螺纹(单独类)从输出流中读取的Python脚本。

public class DistanceController { 
    private DistanceThread distanceThread; 
    private Thread t; 
    private LinkedList<DistanceVT> buffer = new LinkedList<DistanceVT>(); 

    public DistanceController() 
    {    
     t = new Thread(distanceThread); 
     t.start(); 
    } 

    public DistanceVT getDistance() { 
     return buffer.getLast(); 
    } 
} 

这是读取距离的线程,它的想法是它是非阻塞的。

public class DistanceThread implements Runnable { 
private LinkedList<DistanceVT> buffer; 
private String[] args = new String[]{"python", "./run-scripts/distance.py"}; 

public DistanceThread(LinkedList<DistanceVT> list) {buffer = list;} 

@Override 
public void run() { 
    while (true) { 
     try { 
      ProcessBuilder pb = new ProcessBuilder(args); 
      pb.redirectErrorStream(true); 
      final Process p = pb.start(); 
      while (true) { 
       InputStream s = p.getInputStream(); 
       final BufferedReader reader = new BufferedReader(new InputStreamReader(s)); 
       while (((line = reader.readLine()) != null)) { 
        buffer.add(parseDistance(line)); 
       } 
      } 
     } catch (Exception e) { 
     //handle errors 
     } 
    } 
} 

而Python代码看起来像这样(最简单的距离测量代码稍加修改的版本):大家对你的帮助

import time 
import datetime 
from random import randint 

def measure_distance(): 
    time.sleep(0.1) 
    return randint(10,15) 

while True: 
    distance = measure_distance() 
    print ("%s,%s" % (datetime.datetime.now(),distance)) 
+0

您是否可以将所需的代码降低到绝对最小值以重现问题? –

+0

当然吉姆,我会编辑我原来的问题? –

+1

产生输出的过程正在缓冲它。在Java代码中你无能为力。修复Python代码。注意从'Reader'或'InputStream'没有线程读取可能是非阻塞的。当你的阅读线程将输出累积到一个列表中时,它也完全不清楚缓冲的原因。 – EJP

回答

0

感谢。 EJP解决了缓冲问题 - 将一个sys.stdout.flush()添加到Python代码解决了问题。

至于其他的问题 - 你是对的。我的意思是,因为我正在阅读一个单独的线程,程序的主线程可以继续执行其他逻辑。

读线程聚集在由创建它的类传递给它一个列表中的数据。然后可以通过这个包装类访问这些数据,而无需等待输出完成。

import time 
import datetime 
from random import randint 
import sys 

def measure_distance(): 
    time.sleep(0.1) 
    return randint(10,15) 

while True: 
    distance = measure_distance() 
    print ("%s,%s" % (datetime.datetime.now(),distance)) 
    sys.stdout.flush()