Python3 多处理 'for' 循环
Python3 multiprocessing a 'for' loop
我真的很想问这个,因为即使我阅读了文档并看过一些示例也无法真正了解如何使用它。
我有一个 Raspberry pi 3 模型 B,我交叉编译了 QT 5.6 和最新的 SIP 和 PyQt5 版本来开发 Python GUI 并使用 linux 帧缓冲区,一切是成功的,直到我 运行 这部分代码
def refresh_data(self):
if self.setTarget == 1:
for x in range(0, self.targetnum):
self.target.append(getShadowInfo(x))
if float(self.target[x]) != self.datalist[x]:
if float(self.target[x]) > self.datalist[x]:
self.step.append(float(self.target[x]) - self.datalist[x])
self.negative.append(0)
else:
self.step.append(self.datalist[x] - float(self.target[x]))
self.negative.append(1)
else:
self.step.append(0)
self.negative.append(0)
self.step[x] *= 0.1
self.setTarget = 0
self.setTodaysDate(self.year, self.month, self.day, self.hour, self.min)
self.stopv += 10
for x in range(0, self.targetnum):
if self.step[x] != 0:
if self.negative[x] == 0:
self.datalist[x] += self.step[x]
else:
self.datalist[x] -= self.step[x]
self.setCustomParameter(x)
if all(i == 0 for i in self.step):
self.timer.stop()
if self.stopv >= 100:
self.timer.stop()
从外部文件读取数据并将其设置为目标,然后增加或减少实际值以在 python GUI 上更新它,这样看起来很流畅,但同时发生了,性能变差,甚至执行代码的速度比应有的慢(运行 50ms Qtimer)。使用 htop,我注意到当 运行 这部分代码时,我的 RPi 只使用其四个核心中的一个,有人可以帮助我对两个 for 循环进行多处理吗?或者更好的是 refresh_data 函数?.
编辑!
设置自定义参数函数
def setCustomParameter(self, intparameter):
if intparameter == 1:
#RPMMeter
self.hygrometer.setProperty("gaugeValue", round(self.datalist[1], 2))
self.label_5.setText(QCoreApplication.translate("MainWindow", "Engine Speed: " +
str(round(self.datalist[1], 2)) + " RPM"))
if intparameter == 2:
#Pressure
self.label.setText(QCoreApplication.translate("MainWindow",
str(round(self.datalist[2], 2)) + " KPa"))
self.progressBar.setProperty("value", self.datalist[2])
if intparameter == 3:
self.thermometer.setProperty("thermoValue", round(self.datalist[3], 2))
if intparameter == 4:
self.KW_Meter.setProperty("gaugeValue", round(self.datalist[4], 2))
if intparameter == 5:
self.Battery_bank_label.setText(QCoreApplication.translate("MainWindow",
"Battery Bank Voltage: " + str(round(self.datalist[5], 2)) + "V (MEDIUM)"))
看起来你可以通过将(两个 for 循环,1 all
这也是一个 for 循环)减少到 1 个 for 循环并巧妙地放置 if 语句来将速度提高 3 倍。
通过压缩目标数据列表。假设 self.target、self.negative、self.datalist 和 self.step 都是相同的长度。
for i, (t, d) in enumerate(zip(self.target, self.datalist)):
t = float(t)
if (t != d) and (t > d) and (self.setTarget == 1):
self.target.append(getShadowInfo(x))
self.datalist = d + (t - d) * .1
elif (t != d) and (t <= d) and (self.setTarget == 1):
self.target.append(getShadowInfo(x))
self.datalist = d - (d - t) * .1
else:
self.setCustomParameter(i)
if self.setTarget == 1
self.setTarget = 0
self.setTodaysDate(self.year, self.month, self.day, self.hour, self.min)
如果您能够弄清楚如何减少到 1 个 for 循环,则可以通过从 multiprocessing.pool.Pool
:
返回索引和数据来完全替换 for 循环来对其进行多处理
# replacing ... self.datalist = d - (d - t) * .1
# with ... return i, d - (d - t) * .1
results = mp.Pool(4).starmap(return_data, zip(self.target, self.datalist))
for i, d in results:
self.datalist[i] = d
注意:诀窍是弄清楚如何处理需要更新的内容而不在 for 循环
中改变 self.target
我真的很想问这个,因为即使我阅读了文档并看过一些示例也无法真正了解如何使用它。
我有一个 Raspberry pi 3 模型 B,我交叉编译了 QT 5.6 和最新的 SIP 和 PyQt5 版本来开发 Python GUI 并使用 linux 帧缓冲区,一切是成功的,直到我 运行 这部分代码
def refresh_data(self):
if self.setTarget == 1:
for x in range(0, self.targetnum):
self.target.append(getShadowInfo(x))
if float(self.target[x]) != self.datalist[x]:
if float(self.target[x]) > self.datalist[x]:
self.step.append(float(self.target[x]) - self.datalist[x])
self.negative.append(0)
else:
self.step.append(self.datalist[x] - float(self.target[x]))
self.negative.append(1)
else:
self.step.append(0)
self.negative.append(0)
self.step[x] *= 0.1
self.setTarget = 0
self.setTodaysDate(self.year, self.month, self.day, self.hour, self.min)
self.stopv += 10
for x in range(0, self.targetnum):
if self.step[x] != 0:
if self.negative[x] == 0:
self.datalist[x] += self.step[x]
else:
self.datalist[x] -= self.step[x]
self.setCustomParameter(x)
if all(i == 0 for i in self.step):
self.timer.stop()
if self.stopv >= 100:
self.timer.stop()
从外部文件读取数据并将其设置为目标,然后增加或减少实际值以在 python GUI 上更新它,这样看起来很流畅,但同时发生了,性能变差,甚至执行代码的速度比应有的慢(运行 50ms Qtimer)。使用 htop,我注意到当 运行 这部分代码时,我的 RPi 只使用其四个核心中的一个,有人可以帮助我对两个 for 循环进行多处理吗?或者更好的是 refresh_data 函数?.
编辑!
设置自定义参数函数
def setCustomParameter(self, intparameter):
if intparameter == 1:
#RPMMeter
self.hygrometer.setProperty("gaugeValue", round(self.datalist[1], 2))
self.label_5.setText(QCoreApplication.translate("MainWindow", "Engine Speed: " +
str(round(self.datalist[1], 2)) + " RPM"))
if intparameter == 2:
#Pressure
self.label.setText(QCoreApplication.translate("MainWindow",
str(round(self.datalist[2], 2)) + " KPa"))
self.progressBar.setProperty("value", self.datalist[2])
if intparameter == 3:
self.thermometer.setProperty("thermoValue", round(self.datalist[3], 2))
if intparameter == 4:
self.KW_Meter.setProperty("gaugeValue", round(self.datalist[4], 2))
if intparameter == 5:
self.Battery_bank_label.setText(QCoreApplication.translate("MainWindow",
"Battery Bank Voltage: " + str(round(self.datalist[5], 2)) + "V (MEDIUM)"))
看起来你可以通过将(两个 for 循环,1 all
这也是一个 for 循环)减少到 1 个 for 循环并巧妙地放置 if 语句来将速度提高 3 倍。
通过压缩目标数据列表。假设 self.target、self.negative、self.datalist 和 self.step 都是相同的长度。
for i, (t, d) in enumerate(zip(self.target, self.datalist)):
t = float(t)
if (t != d) and (t > d) and (self.setTarget == 1):
self.target.append(getShadowInfo(x))
self.datalist = d + (t - d) * .1
elif (t != d) and (t <= d) and (self.setTarget == 1):
self.target.append(getShadowInfo(x))
self.datalist = d - (d - t) * .1
else:
self.setCustomParameter(i)
if self.setTarget == 1
self.setTarget = 0
self.setTodaysDate(self.year, self.month, self.day, self.hour, self.min)
如果您能够弄清楚如何减少到 1 个 for 循环,则可以通过从 multiprocessing.pool.Pool
:
# replacing ... self.datalist = d - (d - t) * .1
# with ... return i, d - (d - t) * .1
results = mp.Pool(4).starmap(return_data, zip(self.target, self.datalist))
for i, d in results:
self.datalist[i] = d
注意:诀窍是弄清楚如何处理需要更新的内容而不在 for 循环
中改变self.target