【问题标题】:Python: threaded reading from multiple filesPython:从多个文件中线程读取
【发布时间】:2013-03-30 20:14:50
【问题描述】:

我总共有 10 个文件(有时可能会更多 - 但这将是一个固定数量)。

它们很小 - 大约 80 字节。

虽然从他们那里阅读一切都很好并且有效 - 它很慢。 我猜是因为脚本一一处理它们并等待 IO - 所以我开始阅读 Threading and Queue 但我无法想出一个可行的解决方案......

谁能给我一个打开多个线程文件的例子吗?

我想把代码放到几个线程中:

    try:
    with open("/home/pi/sensoren/sensor1", "r") as sensor1, open("/home/pi/sensoren/sensor2", "r") as sensor2, open("/home/pi/sensoren/sensor3", "r") as sensor3, open("/home/pi/sensoren/sensor4", "r") as sensor4, open("/home/pi/sensoren/sensor5", "r") as sensor5, open("/home/pi/sensoren/sensor6", "r") as sensor6, open("/home/pi/sensoren/sensor7", "r") as sensor7, open("/home/pi/sensoren/sensor8", "r") as sensor8, open("/home/pi/sensoren/sensor9", "r") as sensor9, open("/home/pi/sensoren/sensor10", "r") as sensor10:

        sensoren = [sensor1, sensor2, sensor3, sensor4, sensor5, sensor6, sensor7, sensor8, sensor9, sensor10] 
        temp = [ ]

        #CRC checker
        def checkCrc(line):
            if "YES" in line:
                return True
            return False

        #Temperatur Funktion
        def getTemp(line):
            temp = line.rstrip("\n")
            temp = temp.split("t=")
            temp = temp[1]
            #den -62 error abfangen - sollte klappen
            if temp == "-62":
                temp = "00"
            return str(temp)


        #Temperaturen auslesen und zuweisen
        for currentSensor in sensoren:

            if checkCrc(currentSensor.readline()):
                #CRC OK
                temp.append(getTemp(currentSensor.readline()))

            else:
                #CRC ERROR
                temp.append("00")

except IOError as e:
    print("Fehler bei Dateioperationen: %s" % e.strerror)

【问题讨论】:

  • 发布一些您尝试过的代码,指定哪些代码不起作用。这会让你的问题更具建设性。
  • 文件存储在什么样的设备上?
  • 从路径来看,Raspberry PI。我们甚至为此设置了Raspberry PI Stack Exchange

标签: python


【解决方案1】:

读取小文件并不慢,只要你一口气完成。

首先,我们创建一个 80 字节的测试文件;

dd if=/dev/random of=test1.dat bs=80 count=1

然后我们定义一个函数来读取所有内容;

In [1]: def readfile(name):
   ...:     with open(name) as f:
   ...:         data = f.read()
   ...:     return data
   ...: 

然后,计时运行(从普通硬盘读取,而不是 SSD):

In [3]: %timeit readfile('test1.dat')
10000 loops, best of 3: 18.1 us per loop

所以读取这样一个文件需要 18 μs。我不会说那么慢。

当我创建 9 个这样的测试文件并循环读取它们时:

In [3]: %timeit for i in xrange(1,10): readfile('test{:d}.dat'.format(i))
1000 loops, best of 3: 184 us per loop

有了循环开销,每个文件仍然只有大约 21 μs。

编辑:

看过您的代码后,它的功能似乎相当复杂。我会这样组织它:

data = []
temp = []
for sn in ['/home/pi/sensoren/sensor{:d}'.format(i) for i in range(1,11)]: 
                                                            #xrange if Python 2.x
    with open(sn) as f:
        data.append(f.read())
# the data list now contains all sensor data
for num, s in enumerate(data):
    # check for CRC
    d = s.strip()
    if d.startswith("YES"):
        t = d.split("t=")
        # populate temp list
        if t[1] == '-62':
            temp.append("00")
        else:
            temp.append(t[1])

优点:

  • 这会一次性读取每个传感器文件。
  • 它还删除了每个传感器的两个函数调用。
  • 打字少了很多。

【讨论】:

  • 结论是:不要为此使用线程,开销可能只会让它变慢!
  • 感谢您的帮助 - 然而,问题似乎出在其他地方。看起来探测信息只是在文件被访问时才被收集——这会减慢它的速度。所以似乎不是文件访问是这里的问题。感谢您的帮助-无论如何我都会为文件制作一个正确的循环! :)
  • @Jrc:您应该检查文件是打开还是读取时生成的信息。在前一种情况下,您可以先在单独的循环中打开和关闭所有文件,然后再读取它们,从而节省一些时间。
  • @Jrc:请记住,有些传感器很慢。以前的计算机有一个传感器芯片,可以报告 i2c 上的电压和温度。 IIRC,它每秒只提供一次新值...
  • 是的,它很慢 - 从所有传感器获取数据平均需要大约 8 秒。必须使用它!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 2013-08-20
  • 1970-01-01
  • 2010-11-28
  • 1970-01-01
相关资源
最近更新 更多